Object Oriented Graphics And Painters - oop

When creating an object that will be graphically represented but also have data and functionality independent of that representation (i.e., a card in a card game will have a graphic, but also know its value, suit, maybe be able to flip over), from a best practices approach, should that object know its own image and position?
If not, how should it be handled? I understand that at the very least another class should be responsible for drawing said object, and it appeals to me that the class shouldn't need to be concerned with its graphics at all: the program should be able to change the design and look of the cards without impacting the class itself - a seven of spades is a seven of spades no matter how you draw it - but I'm finding it difficult to think up a solution to having the 'drawer' class know the image and location of the card.
My present solution is to have a sprite class, and the card contains a sprite object, which is constructed along with the card - the sprite simply contains an image and vector (location), but I feel that I could break this down.
Any design patterns or common sense solutions I'm missing? Or am I just thinking incorrectly that this should be separated?

Since this is a matter of opinion: I believe it would be best for the object not to know its own image. It should know its own position. When a card is drawn, like you mentioned, a Seven of Spades is a Seven of Spades. Leave it to a different handler to draw the image based on what type of card it is, rather than asking the card for its image.
When you draw a card, you could make a method call, ex: drawCardImage(cardObject.type). The method could then check, using if statements, "if card == 'sevenofspades': draw("/images/sevenspades.png")

Related

Make rectangle fall when being hit by ball (different outcomes depending on properties)

I've just got started with physics. I'm using Java, though language does not matter obviously. Now I though I'd do something like this:
A ball with a certain speed, radius and mass hits a rectangle with a certain mass, width and height. Depending on where the ball hits the rectangle (how high up), and all the properties the ball and the rectangle have that i just mentioned, there will be different outcomes of the situation.
These are the four possible outcomes:
The ball bounces back because the rectangle was too heavy
The rectangle starts to wobble, but then goes back to normal
The rectangle falls to the right
The ball strikes through making the rectangle fall to the left
Please note, I don't expect you to write a program for me. I understand it is a lot to think off. But I have no idea how to start. I would really appreciated some guide lines and links to further reading about this (I was not sure what to google to find info about this.)
And also, I'm doing this to learn, so don't tell me to use an engine or anything like that.
You are trying to build a simple physics simulator. This is a pretty involved problem, and you'll have to learn a certain amount of physics along the way.
I suggest you develop the simulator to handle these situations, roughly in this order:
An object moves through space (constant velocity, no gravity).
An object moves under the influence of a constant force (such as gravity).
An object moves with a constraint (e.g. a pendulum, a rolling square).
An object slides across a surface, with friction (both static and kinetic).
Two objects collide inelastically (they stick).
Two objects collide elastically (they bounce).
Once you have all of these, you will be able to simulate your ball and rectangle.

How to code a random movement in limited area

I have a limited area (screen) populated with a few moving objects (3-20 of them, so it's not like 10.000 :). Those objects should be moving with a constant speed and into random direction. But, there are a few limitation to it:
objects shouldn't exit the area - so if it's close to the edge, it should move away from it
objects shouldn't bump onto each other - so when one is close to another one it should move away (but not get too close to different one).
On the image below I have marked the allowed moves in this situation - for example object D shouldn't move straight up, as it would bring it to the "wall".
What I would like to have is a way to move them (one by one). Is there any simple way to achieve it, without too much calculations?
The density of objects in the area would be rather low.
There are a number of ways you might programmatically enforce your desired behavior, given that you have such a small number of objects. However, I'm going to suggest something slightly different.
What if you ran the whole thing as a physics simulation? For instance, you could set up a Box2D world with no gravity, no friction, and perfectly elastic collisions. You could model your enclosed region and populate it with objects that are proportionally larger than their on-screen counterparts so that the on-screen versions never get too close to each other (because the underlying objects in the physics simulation will collide and change direction before that can happen), and assign each object a random initial position and velocity.
Then all you have to do is step the physics simulation, and map its current state into your UI. All the tricky stuff is handled for you, and the result will probably be more believable/realistic than what you would get by trying to come up with your own movement algorithm (or if you wanted it to appear more random and less believable, you could also just periodically apply a random impulse to a random object to keep things changing unpredictably).
You can use the hitTest: method of UIView
UIView* touchedView=[self.superview hitTest:currentOrigin withEvent:nil];
In This method you have to pass the current origin of the ball and in second argument you can pass nil.
that method will return the view with which the ball is hited.
If there is any hit view you just change the direction of the ball.
for border you can set the condition for the frame of the ball if the ball go out of the boundary just change the direction of the ball.

How to check the color of a certain part of an image?

I am making a simple game that uses "AI players" (they aren't really AI players). I need to find out if a certain part of the "map" I am using has certain colors, so I can make the "AI players" do certain things. Is it possible to do this?
I don't know if this will help, but a game called "Warcraft 3" uses a very similar thing to determine certain things, such as movement. If you know of this game, it should be a lot easier to understand this question.
I think this may be possible if I put the image into a custom NSView subclass, but I have not yet learned how to check colors there either.
The best way to do this would be not to bother checking the colors of the actual image (which can be an expensive operation if you're checking a lot of individual pixels), but to indicate in your map's data structure the characteristics you want to have, and then take both the color and player behavior from that.
In pseudocode:
// Draw Map
foreach currSquare in listOfSquares:
if map[currSquare].hasPropertyX():
drawSquare(currSquare, blue)
else if map[currSquare].hasPropertyY():
drawSquare(currSquare, red)
// Move pieces
foreach currPlayer in listOfPlayers:
squareIAmStandingOn = currPlayer.square
if map[squareIAmStandingOn].hasPropertyX():
currPlayer.takeActionX()
else if map[squareIAmStandingOn].hasPropertyY():
currPlayer.takeActionY()
Create a NSBitmapImageRep from the NSImage and use colorAtX:y: to get the color.
Check:
NSBitmapImageRep Class Reference

Objective-C draw a path and detect when it closes (forms a closed shape)

I'm fairly new to game programming (but not to programming) and I want to create a space ship which leaves a trail on the screen. Now my problem is to come up with a solution how to detect if the trail left from the ship forms a closed shape - eg. if the ship left a trail around an object, the object is caught inside its trail so to speak.
The direction I'm thinking is to draw the path of the trail on an image not visible on the screen and every now and then try to fill it with certain color and then check if fill is caught within the trail path. However it seems like a lot of overhead.
Any ideas how to do that? I'm using cocos2d if that's of any help
In game programming you often need to think more mathematically than visually.
First does your ship continuously leaves a trail on the screen? If yes, then it will be easier to know when the shape closes : you just have to remember the coordinate where your ship started to leave a trail, then wait for the trail to approach this coordinate another time (for example within a radius of 10 pixels, or else the user will need to be really accurate to hit exactly the same pixel to close the shape).
The visual representation of the trail is only here for the user, you'll never use it to compute anything. What you will do is to keep in memory the path followed by the ship's trail : a polygon, which is nothing else than the list of coordinates it followed.
Then after you know that your shape is closed, you have to determine if an object is inside your polygon or not. It's possible that objective-c or cocos2d (I don't know much about it) already contains a built-in function to know if a point is inside a polygon. In java there is the Polygon class which makes this really easy. If you don't find anything you can do it yourself, there are already great answers about this subject on SO, here is a nice one : How can I determine whether a 2D Point is within a Polygon?

Simple Drawing App Design -- Hillegass Book, Ch. 18

I am working through Aaron Hillegass' Cocoa Programming for Mac OS X and am doing the challenge for Chapter 18. Basically, the challenge is to write an app that can draw ovals using your mouse, and then additionally, add saving/loading and undo support. I'm trying to think of a good class design for this app that follows MVC. Here's what I had in mind:
Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval.
Have a main view (JBDrawingView) that holds JBOvals and draws them.
The thing is that I wasn't sure how to add archiving. Should I archive each JBOval? I think this would work, but archiving an NSView doesn't seem very efficient. Any ideas on a better class design?
Thanks.
Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval.
That doesn't sound very MVC. “JBOval” sounds like a model class to me.
Have a main view (JBDrawingView) that holds JBOvals and draws them.
I do like this part.
My suggestion is to have each model object (JBOval, etc.) able to create a Bézier path representing itself. The JBDrawingView (and you should come up with a better name for that, as all views draw by definition) should ask each model object for its Bézier path, fill settings, and stroke settings, and draw the object accordingly.
This keeps the knowledge of how to draw (the path, line width, colors, etc.) in the various shape classes where they belong, while also keeping the actual drawing code in the view layer where it belongs.
The answer to where to put archiving code should be intuitively obvious from this point.
Having a whole NSView for each oval seems rather heavyweight to me. I would descend them from NSObject instead and just have them draw to the current view.
They could also know how to archive themselves, although at that point you'd probably want to think about pulling them out of the view and thinking of them more as part of your model.
Your JBOval views would each be responsible for drawing themselves (basically drawing an oval path and filling it, within their bounds), but JBDrawingView would be responsible for mousing and dragging (and thereby sizing and positioning the JBOvals, which would be its subviews). The drawingView would do no drawing itself.
So far as archiving, you could either have a model class to represent each oval (such as its bounding rectangle, or any other dimensions you choose to represent each oval with). You could archive and unarchive these models to recreate your views.
Finally, I use the JB prefix too, so … :P at you.