I've always had issues with classes, and I'm not sure if this is possible.
I'm trying to create a class with an identifiable name.
I realize that that isn't clear, but my overall goal is to create a grid-like game and each square in the grid would be a member in the class.
So for example, I would have a class called square and say in my code
square(16,47).isdead = true;
Basically, I want to know if it is possible to create a class where I can differentiate between at least a hundred different squares.
Also, not sure if this matters, but I am using sprite kit.
Several ways to do what you want, I would prefer the below method.
C style two dimensional array:
Square * squares[10][10];
And you encapsulate that in a class called SquareManager with a method:
-(Square*) aSquareManager squareX:(short)x Y:(short)y;
If you specifically want the access pattern described in your question you can use (credit goes to arturgrigor):
#define square(x, y) [aSquareManager squareX:x Y:y]
Then you can access all of your squares this way:
if ([aSquareManager squareX:16 Y:47].isdead==true) [self showSkullForSquare:[aSquareManager squareX:16 Y:47]];
A different approach would be that a square has x and y properties:
Square.h
#property short y;
#property short x;
And then you put them all into an array, and when you need a square you search through the array.
for(Square * aSquare in squares) {
if(aSquare.x==anXValue && aSquare.y==anYValue) {
return aSquare;
}
}
Functions like these are much quicker than you think.
Related
I'm using Paintcode V3 and last Xcode for my project.
In Paintcode I draw a red path, kind of "clock hand" with a radius variable to be able to rotate it.
In my Xcode project, this custom UIView is added to a main view.
When the red path is rotating, I need to know when it intersects with another element of the view.
I tried:
if self.redPathView.frame.intersects(self.anotherView.frame) {
//do something...
}
but it can't work because redPathView is the entire Paintcode canvas (the square frame) and not only the red path.
I'm searching a way to access to the red path of my view.
Interesting problem.
I don't think there is a way to do exactly what you are looking for...
Like you mentioned, when we use PaintCode, our custom drawings become an entire UIView.
We can't access its specific elements (like your redPathView).
(I'm favoriting this question in case anyone knows if we actually can. I may be wrong.)
Anyway, there is a workaround. You could use PaintCode itself to tell you when "collisions" happen. Of course, then you would need to draw everything there... And implement some sort of internal control that would make sense to you.
For example, in the picture below I created this "clock hand", with functions to detect when the red thing touches other UI elements (key point there is the touchedElementID expression -- observe how it updates itself with the "ID" of the rectangles):
There are some issues you may find with this approach, for example the need to know the exact position of other elements on the screen and possibly complex ternary constructions like:
(rotationSanitized <= -352 || rotationSanitized >= -8) ?
1 :
(rotationSanitized <= -82 && rotationSanitized >= -98) ?
2 :
(rotationSanitized <= -172 && rotationSanitized >= -188) ?
3 :
(rotationSanitized <= -262 && rotationSanitized >= -278) ?
4 : 0
Also, how to "export" and consume this information along with the StyleKit in Xcode?
The trick I did was to add an empty (no Fill, no Stroke) UI element in PaintCode and associate the touchedElementID expression result to the alpha value of the element.
This way I could access the expression in my custom view, for example via StyleKit.touchedElementID. But that introduces a new problem since now I have to change the generated StyleKit every time it is exported (two lines of code, but still). That is kind of a fragile solution.
However, if you are ok with that, then it's just a matter of consuming this new information...
For that I created a protocol, so my ViewController can act as the delegate of my custom view, and perform whatever it needs to do when the most internal UI elements in PaintCode are "touched".
Here is the final result:
Finally, check this project in GitHub with all the code and samples.
I recently posted a question on here
Randomly generated tunnel walls that don't jump around from one to the next
That pretty much said I was getting a "drunken walk" tunnel instead of a correlated one due to a lack of an algorithm.
The answer works to an extent for what I'm attempting to create but I couldn't figure out how to implement the algorithm properly for my game.
I believe step one is to create the offsets for the pairs of walls. I want the images that appear (named: "Left1" and "Right1" , "Left2 and "Right2".... "Left41" and Right41") on each side of the screen to be "re-spawning" slightly offset to the left or right in succession of each other in order to create the illusion of a tunnel in appearance. I attempted to use the code provided to me in an answer to create an offset for a set of my walls but I get few errors when attempting to build. It was telling me first that a local declaration of 'Left1' hides instance variable, which I believe is because it's been declared already as a variable within my function? That came up twice.. Along with that I have an error that says Assigning to 'UIImageView *__strong' from incompatible type 'float'. How can I fix these? Or is it something I'm doing wrong elsewhere?
I'm kind of lost on this part since I don't know how to really rearrange it, due to the semantic issues.
I can answer any questions about the program to make it easier to assess the situation.
-(void) TunnelMovement{
CGFloat Left1 = 14;
for( int i = 0; i < 41; i++ ){
CGFloat offset = (CGFloat)arc4random_uniform(2*100) - 100;
Left1 += offset;
Right1 = Left1 + 14;
//...
}
}
This is what I have exactly in my code after trying to fill in the blanks from the answer given. Not sure if I put in all the necessities or what. Thank you.
[I can give you quick correction on that error message, but you are trying to run and you can't even walk yet, you can barely crawl.
Stack Overflow is a programming forum but it is not the place to learn or teach programming, people won't have the patience to teach basics.]
You can't assign the value of one thing to another if they are totally different things. In the line:
Right1 = Left1 + 14;
Right1 is a UIImageView and Left1 is a CGFloat, they are completely different things. Left1 is just a simple number, Right1 is a complex object.
You're trying to position UIImageView so you need to assign the value of Left1 + 14 to a part of the UIImageView that will position it and which is also a CGFloat.
So you need to assign it to something like the bounds or the frame or the center's x value, such as
Right1.center.x = Left1 + 14;
The warning is because you have two different things with the same name, you have UIImageView called Left1 but then you have a CGFloat also called Left1, you shouldn't give the same name to two different things - the CGFloat Left1 hides the UIImageView called Left1. You should have called it Left1X or LeftWallX or similar as it is in the answer to your other question.
That's just the error and warning, you're probably not ready to move on to the semantics of how to draw the maze if you were strugging with these two. In particular you will as a minimum need to know what the bounds, frame, center, x, y, CGPoint, CGRect, CGSize all are in order to fully understand what value to change and what effect changing those values will have on the position of the UIImageViews.
---- EDIT --- object programming 101
When you have an object like UIImageView it is like a having a house, the house can have a name and have lots of rooms in it, each with a name, within each room there are lots of things. You are trying to do the equivalent of replace the old television in one room with a new television.
So Right1 is like a house
Right1.center is like a room in a house
Right1.center.x is like the television in the room called center which is in the house called Right1.
Right1 = Left1 + 14;
is like trying to swap a new television for a house, instead of trying to swap it for a televsion within a room within a house.
Is that analogy too dumb?
I'm building an arithmetic app & in it there are subclasses of NSObject for Numbers and Digits.Both of these have corresponding view objects which take a Datasource (either number or digit) and a delegate, the view controller.
I have found that it is useful in getting the views & the model to work together to set the digit views as a property of their corresponding digits.
For example, the Number class has an NSMutableArray property that holds its digits.
If I want to find the size for the corresponding NumberView, I write can write code like this in the controller:
-(void) updateNumberViewFrameSize:(ACNumberView*) sender
{
NSUInteger i;
float width = 0, height = 0;
for (ACDigit* digit in [sender.dataSource returnNumberViewDataSource].digitArray)
{
width += digit.digitView.size.width;
height += digit.digitView.size.width;
}
sender.frame = CGRectMake(sender.frame.origin.x, sender.frame.origin.y, width, height);
}
The code works just fine, but I feel that it is not good practice to hold that pointer to the view from the model, even if the model isn't using it itself.
If it is bad practice, what are the potential pitfalls, and Is there a better way to achieve this type end ?
First: You are right. This is no good design.
Second: You calculate the size of a number view inside the model. But a number view should know its size itself. It knows the number through its data source and can get the digits. So it has all information for calculating its size.
To show the problem, just imagine (even this situation is on iOS not that common), that you display the same number at two places (= with to different number views). This would break your model. Why?
Solution: Put all code related to a graphic state (drawing, size, …) into the number view and digit view. On half of the way that will be additional work. But at the end, when every code is migrated to the view layer, it is as easy as computing it inside the model.
I have a little logical problem over here.
As the title says, I try to build a boardgame as a computer-program (maybe with internet-support, but thats another story)
As for now, I have a map, which has some crossroads in it, hence I cannot simply define the fields as '1, 2, 3, 4, ...' because if there is a crossroad at field 10, I would have more than one field which has to be labeled 11 (Because then there is a field left and right of field 10, for example.)
So the problem is, if I cannot define the Board in numbers then I cannot simply get the possible positions a player can take when he rolls 2d6-dices with calculating 'Field-Nr. + RandomRange(1,6) + RandomRange(1,6)'
Does anybody have an idea, how to define a Map like this on another way, where I still can calculate the possible new-fields for Player X with a 2d6-dice-roll?
Thanks in advance.
If i understand well... (i don't thing so) this might help you. Just use dynamic arrays for your boardgame field and change your actions after the dimensions x,y .... Look at this "type Name = array of {array of ...} Base type; // Dynamic array"
It sounds like you have a graph of connected vertices. When a player is at a particular vertex of N edges, assuming N < 12, the new Field will be reached from traversing edge number N % ( rand(6) + rand(6) ).
You could also just do rand(12), but that would have an even distribution, unlike 2d6.
Instead of dynamic arrays, I would recommend using a linked-list of records to describe the surrounding cells, and traverse the player's location and possible moves using that linked-list.
First, define a record that describes each cell in your board's playable grid (the cells on the grid can be four-sided like a chessboard, or hexagonal like in Civilization V) ... each cell record should contain info such as coordinates, which players are also in that cell, any rewards/hazards/etc that would affect gameplay, etc. (you get the idea).
Finally, the linked-list joins all of these cells, effectively pointing to any connected cells. That way, all you'd need is the cell location of Player X and calculate possible moves over n amount of cells (determined by the dice roll), traversing the adjoining cells (that don't have hazards, for example).
If all you want is to track the possible roads, you can also use this approach to identify possible paths (instead of cells) Player X can travel on.
I have created a single player game using iOS + Cocos2d + Chipmunk and I'm looking for a solution that demonstrates how to attach multiple collision shapes to a single rigid body. I have a target that has an irregular shape (a car) that I need to detect collisions for. The target (car) is seen by the player from a side view and other objects may impact the target from multiple directions, not just from the front or the rear. The shape is such that I am unable to use a single cpPolyShape and achieve a realistic collision effect. Two cpPolyShapes (rectangular) stacked on top of each other, with the bottom rectangle being larger should do the trick.
Can someone provide a example of how this can be achieved?
I read the Chipmunk docs about cpShape, http://code.google.com/p/chipmunk-physics/wiki/cpShape, and it states that 'You can attach multiple collision shapes to a rigid body' in the very bottom of the page in the notes section, but no example is provided.
I currently have a working, functional project and am trying to make some final adjustments to improve game play.
When you call cp*ShapeNew(), the first parameter is the body to attach it to. Simple make more than one shape that share the same body. There is no trick.
You can add the method
In the .h file add the prototype
static int FunctionName (cpArbiter *arb, cpSpace *space, void *unused);
Now in the .m file add the code as
cpSpaceAddCollisionHandler(<space name>, <cpCollisionType of body a >, <cpCollisionType of body b>, <cpCollisionBeginFunc name>, <cpCollisionPreSolveFunc preSolve>, <cpCollisionPostSolveFunc postSolve>, <cpCollisionSeparateFunc separate>, <void *data>);
static int FunctionName(cpArbiter *arb, cpSpace *space, void *unused)
{
cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
printf("\n Collision Detected");
return 1;
}
Note:- Don't Forget to give the collision type of both Body.