250 lines
7.5 KiB
Objective-C
250 lines
7.5 KiB
Objective-C
#import "GameScene.h"
|
|
|
|
@implementation GameScene
|
|
|
|
@synthesize player, boxes, levels, background, scoreLabel, levelLabel, godmodeLabel;
|
|
@synthesize lastUpdateTime, pauseBeforeBoxDrop, boxDropDelay;
|
|
@synthesize score, currentLvl, godmode;
|
|
|
|
-(void)didMoveToView:(SKView *)view {
|
|
boxes = [NSMutableArray new];
|
|
levels = [NSMutableArray new];
|
|
|
|
self.size = CGSizeMake(640, 480);
|
|
|
|
background = [SKSpriteNode new];
|
|
player = [Entity new];
|
|
scoreLabel = [SKLabelNode new];
|
|
levelLabel = [SKLabelNode new];
|
|
godmodeLabel = [SKLabelNode new];
|
|
|
|
[self backGrInit];
|
|
[self playerInit];
|
|
[self scoreLabelInit];
|
|
[self levelLabelInit];
|
|
[self godmodeLabelInit];
|
|
|
|
for (int i = 0; i < NUMBER_OF_LVLS; i++) {
|
|
Level *newLvl = [Level new];
|
|
newLvl.goal = (i+1)*2;
|
|
newLvl.delayDec = 0.5*i;
|
|
[levels addObject:newLvl];
|
|
}
|
|
|
|
godmode = false;
|
|
|
|
[self newGame];
|
|
|
|
|
|
//-----
|
|
SKLabelNode *test = [SKLabelNode new];
|
|
test.fontName = @"Arial";
|
|
test.position = CGPointMake(TILE_SIZE*2, TILE_SIZE*2);
|
|
test.text = @"Test";
|
|
test.fontColor = [NSColor blackColor];
|
|
test.fontSize = 8;
|
|
[self addChild:test];
|
|
}
|
|
|
|
-(void)backGrInit {
|
|
background = [SKSpriteNode spriteNodeWithImageNamed:@"BG.png"];
|
|
background.anchorPoint = CGPointMake(0, 0);
|
|
background.position = CGPointMake(0, 0);
|
|
[self addChild:background];
|
|
}
|
|
|
|
-(void)playerInit {
|
|
SKTexture *playerTexture = [SKTexture textureWithImageNamed:@"Player.png"];
|
|
player = [Entity spriteNodeWithTexture:playerTexture];
|
|
player.anchorPoint = CGPointMake(0, 0);
|
|
player.size = CGSizeMake(TILE_SIZE, TILE_SIZE*1.5);
|
|
[self addChild:player];
|
|
}
|
|
|
|
-(void)scoreLabelInit {
|
|
scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
|
|
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
|
|
scoreLabel.position = CGPointMake(TILE_SIZE, self.size.height - TILE_SIZE);
|
|
scoreLabel.fontColor = [NSColor blackColor];
|
|
scoreLabel.fontSize = 24;
|
|
[self addChild:scoreLabel];
|
|
}
|
|
|
|
-(void)levelLabelInit {
|
|
levelLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
|
|
levelLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
|
|
levelLabel.position = CGPointMake(TILE_SIZE, self.size.height - TILE_SIZE*1.5);
|
|
levelLabel.fontColor = [NSColor blackColor];
|
|
levelLabel.fontSize = 24;
|
|
[self addChild:levelLabel];
|
|
}
|
|
|
|
-(void)godmodeLabelInit {
|
|
godmodeLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
|
|
godmodeLabel.hidden = true;
|
|
godmodeLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
|
|
godmodeLabel.position = CGPointMake(self.size.width - TILE_SIZE, self.size.height - TILE_SIZE);
|
|
godmodeLabel.fontColor = [NSColor blackColor];
|
|
godmodeLabel.fontSize = 8;
|
|
godmodeLabel.text = @"Godmode";
|
|
[self addChild:godmodeLabel];
|
|
}
|
|
|
|
-(void)newGame {
|
|
currentLvl = 0;
|
|
pauseBeforeBoxDrop = 0;
|
|
lastUpdateTime = 0;
|
|
boxDropDelay = 2;
|
|
score = 0;
|
|
player.position = CGPointMake(TILE_SIZE*5, TILE_SIZE*2);
|
|
[player removeAllActions];
|
|
|
|
for (int i = 0; i < boxes.count; i++) {
|
|
[boxes[i] removeFromParent];
|
|
}
|
|
|
|
[boxes removeAllObjects];
|
|
}
|
|
|
|
-(void)update:(CFTimeInterval)currentTime {
|
|
CFTimeInterval timeSinceLastUpdate = currentTime - lastUpdateTime;
|
|
lastUpdateTime = currentTime;
|
|
if (timeSinceLastUpdate > 1) {
|
|
timeSinceLastUpdate = 1.0 / 60.0;
|
|
lastUpdateTime = currentTime;
|
|
}
|
|
|
|
[player resetCollisions];
|
|
scoreLabel.text = [NSString stringWithFormat:@"Score:\t%d", score];
|
|
levelLabel.text = [NSString stringWithFormat:@"Level:\t%d", currentLvl+1];
|
|
for (int i = 0; i < boxes.count; i++) {
|
|
Entity *checkedBox = [boxes objectAtIndex:i];
|
|
|
|
[checkedBox resetCollisions];
|
|
|
|
[player checkCollisionWith:checkedBox];
|
|
[checkedBox checkCollisionWith:player];
|
|
for (int j = 0; j < boxes.count; j++) if (i != j) {
|
|
[checkedBox checkCollisionWith:[boxes objectAtIndex:j]];
|
|
}
|
|
|
|
[checkedBox checkCollisionWithRoomWithWidth: self.size.width];
|
|
[checkedBox fall];
|
|
|
|
[self checkForPlayerIsBlockedBy: checkedBox];
|
|
}
|
|
|
|
pauseBeforeBoxDrop += timeSinceLastUpdate;
|
|
if (pauseBeforeBoxDrop > boxDropDelay) {
|
|
pauseBeforeBoxDrop = 0;
|
|
boxDropDelay = [self getRandomNumberBetween:1 and:4] - ((Level *)levels[currentLvl]).delayDec;
|
|
[self newBox];
|
|
}
|
|
|
|
[player checkCollisionWithRoomWithWidth: self.size.width];
|
|
[player fall];
|
|
|
|
[self checkForFullLine];
|
|
}
|
|
|
|
-(void)checkForPlayerIsBlockedBy:(Entity *) checkedBox {
|
|
if (player.isBlockedFromUp) {
|
|
if ([player actionForKey:@"jump"]) {
|
|
[checkedBox removeFromParent];
|
|
[boxes removeObject:checkedBox];
|
|
}
|
|
else {
|
|
if (!godmode) {
|
|
[self newGame];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void)checkForFullLine {
|
|
NSMutableArray *firstLine = [NSMutableArray new];
|
|
for (int i = 0; i < boxes.count; i++) {
|
|
Entity *checkedBox = [boxes objectAtIndex:i];
|
|
if (lround(checkedBox.position.y) == 0) {
|
|
if ((checkedBox.isBlockedFromDown)&&!([checkedBox actionForKey:@"afterFallIdle"])) {
|
|
[firstLine addObject:checkedBox];
|
|
}
|
|
}
|
|
}
|
|
if (firstLine.count > 9) {
|
|
for (int i = 0; i < firstLine.count; i++) {
|
|
Entity *boxForDel = [firstLine objectAtIndex:i];
|
|
[boxForDel removeFromParent];
|
|
[boxes removeObject:boxForDel];
|
|
}
|
|
score++;
|
|
if (score > ((Level *)levels[currentLvl]).goal) {
|
|
currentLvl++;
|
|
score = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void)newBox {
|
|
SKTexture *boxTexture = [SKTexture textureWithImageNamed:@"Box.png"];
|
|
Entity *box = [Entity spriteNodeWithTexture:boxTexture];
|
|
box.size = CGSizeMake(TILE_SIZE, TILE_SIZE);
|
|
box.anchorPoint = CGPointMake(0, 0);
|
|
box.position = CGPointMake(TILE_SIZE*[self getRandomNumberBetween:0 and:9], TILE_SIZE*9);
|
|
[boxes addObject:box];
|
|
[self addChild: [boxes lastObject]];
|
|
}
|
|
|
|
-(void)keyDown:(NSEvent *)theEvent {
|
|
if ([theEvent modifierFlags] & NSNumericPadKeyMask) {
|
|
|
|
NSString *arrow = [theEvent charactersIgnoringModifiers];
|
|
if ([arrow length] == 1) {
|
|
unichar keyChar = [arrow characterAtIndex: 0];
|
|
switch (keyChar) {
|
|
case NSLeftArrowFunctionKey:
|
|
[player moveLeft];
|
|
break;
|
|
case NSRightArrowFunctionKey:
|
|
[player moveRight];
|
|
break;
|
|
case NSUpArrowFunctionKey:
|
|
[player jump];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
NSString *characters = [theEvent characters];
|
|
for (int i = 0; i < [characters length]; i++) {
|
|
unichar c = [characters characterAtIndex: i];
|
|
switch (c) {
|
|
case 'a':
|
|
[player moveLeft];
|
|
break;
|
|
case 'd':
|
|
[player moveRight];
|
|
break;
|
|
case 'w':
|
|
case ' ':
|
|
[player jump];
|
|
break;
|
|
case 'B':
|
|
[self newBox];
|
|
break;
|
|
case 'N':
|
|
[self newGame];
|
|
break;
|
|
case 'G':
|
|
godmode = !godmode;
|
|
godmodeLabel.hidden = !godmode;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
-(int)getRandomNumberBetween:(int)start and:(int)end {
|
|
return start + arc4random()%(end-start+1);
|
|
}
|
|
|
|
@end
|