Files
BoxAttack/boxattack/GameScene.m
T
2022-04-11 17:17:23 +03:00

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