First version
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <SpriteKit/SpriteKit.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
@property (assign) IBOutlet SKView *skView;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,46 @@
|
||||
#import "AppDelegate.h"
|
||||
#import "GameScene.h"
|
||||
|
||||
@implementation SKScene (Unarchive)
|
||||
|
||||
+ (instancetype)unarchiveFromFile:(NSString *)file {
|
||||
/* Retrieve scene file path from the application bundle */
|
||||
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
|
||||
/* Unarchive the file to an SKScene object */
|
||||
NSData *data = [NSData dataWithContentsOfFile:nodePath
|
||||
options:NSDataReadingMappedIfSafe
|
||||
error:nil];
|
||||
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
|
||||
[arch setClass:self forClassName:@"SKScene"];
|
||||
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
|
||||
[arch finishDecoding];
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize window = _window;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
GameScene *scene = [GameScene unarchiveFromFile:@"GameScene"];
|
||||
|
||||
/* Set the scale mode to scale to fit the window */
|
||||
scene.scaleMode = SKSceneScaleModeAspectFit;
|
||||
|
||||
[self.skView presentScene:scene];
|
||||
|
||||
/* Sprite Kit applies additional optimizations to improve rendering performance */
|
||||
self.skView.ignoresSiblingOrder = YES;
|
||||
|
||||
self.skView.showsFPS = YES;
|
||||
self.skView.showsNodeCount = YES;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6245"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="BoxAttack" id="56">
|
||||
<menu key="submenu" title="BoxAttack" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About BoxAttack" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide BoxAttack" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit BoxAttack" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="537">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="538"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="Tim Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="BoxAttack" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||
<rect key="contentRect" x="0.0" y="0.0" width="640" height="480"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="640" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="539" customClass="SKView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="640" height="480"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="539" firstAttribute="bottom" secondItem="372" secondAttribute="bottom" id="541"/>
|
||||
<constraint firstItem="539" firstAttribute="top" secondItem="372" secondAttribute="top" id="542"/>
|
||||
<constraint firstItem="539" firstAttribute="trailing" secondItem="372" secondAttribute="trailing" id="543"/>
|
||||
<constraint firstItem="539" firstAttribute="leading" secondItem="372" secondAttribute="leading" id="544"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</window>
|
||||
<customObject id="494" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="skView" destination="539" id="540"/>
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,34 @@
|
||||
#import <SpriteKit/SpriteKit.h>
|
||||
#import "sceneParam.c"
|
||||
|
||||
@interface Entity : SKSpriteNode
|
||||
{
|
||||
@private
|
||||
BOOL isBlockedFromLeft;
|
||||
BOOL isBlockedFromRight;
|
||||
BOOL isBlockedFromUp;
|
||||
BOOL isBlockedFromDown;
|
||||
Entity *blockedFromLeftBy;
|
||||
Entity *blockedFromRightBy;
|
||||
Entity *blockedFromUpBy;
|
||||
Entity *blockedFromDownBy;
|
||||
}
|
||||
@property BOOL isBlockedFromLeft;
|
||||
@property BOOL isBlockedFromRight;
|
||||
@property BOOL isBlockedFromUp;
|
||||
@property BOOL isBlockedFromDown;
|
||||
@property Entity *blockedFromLeftBy;
|
||||
@property Entity *blockedFromRightBy;
|
||||
@property Entity *blockedFromUpBy;
|
||||
@property Entity *blockedFromDownBy;
|
||||
|
||||
-(void)resetCollisions;
|
||||
-(void)checkCollisionWith:(Entity *) secondEntity;
|
||||
-(void)checkCollisionWithRoomWithWidth:(CGFloat)roomWidth;
|
||||
|
||||
-(void)moveLeft;
|
||||
-(void)moveRight;
|
||||
-(void)fall;
|
||||
-(void)jump;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,105 @@
|
||||
#import "Entity.h"
|
||||
|
||||
@implementation Entity
|
||||
|
||||
@synthesize isBlockedFromLeft, isBlockedFromRight, isBlockedFromUp, isBlockedFromDown;
|
||||
@synthesize blockedFromLeftBy, blockedFromRightBy, blockedFromUpBy, blockedFromDownBy;
|
||||
|
||||
-(void)resetCollisions {
|
||||
self.isBlockedFromLeft = self.isBlockedFromRight = self.isBlockedFromUp = self.isBlockedFromDown = false;
|
||||
self.blockedFromLeftBy = self.blockedFromRightBy = self.blockedFromUpBy = self.blockedFromDownBy = nil;
|
||||
}
|
||||
|
||||
-(void)checkCollisionWith:(Entity *)secondEntity {
|
||||
if ((lround(self.position.x - secondEntity.size.width-1) < lround(secondEntity.position.x))&&
|
||||
(lround(self.position.x - secondEntity.size.width+1) > lround(secondEntity.position.x))) {
|
||||
if ((lround(self.position.y + secondEntity.size.height) > lround(secondEntity.position.y))&&
|
||||
((lround(self.position.y - secondEntity.size.height) < lround(secondEntity.position.y)))) {
|
||||
self.isBlockedFromLeft = true;
|
||||
blockedFromLeftBy = secondEntity;
|
||||
}
|
||||
}
|
||||
if ((lround(self.position.x + self.size.width-1) < lround(secondEntity.position.x))&&
|
||||
(lround(self.position.x + self.size.width+1) > lround(secondEntity.position.x))) {
|
||||
if ((lround(self.position.y + secondEntity.size.height) > lround(secondEntity.position.y))&&
|
||||
((lround(self.position.y - secondEntity.size.height) < lround(secondEntity.position.y))))
|
||||
{
|
||||
self.isBlockedFromRight = true;
|
||||
blockedFromRightBy = secondEntity;
|
||||
}
|
||||
}
|
||||
if ((lround(self.position.x - self.size.width) < lround(secondEntity.position.x))&&
|
||||
(lround(self.position.x + self.size.width) > (secondEntity.position.x))) {
|
||||
if ((lround(self.position.y + self.size.height*0.75) < lround(secondEntity.position.y))&&
|
||||
(lround(self.position.y + self.size.height+1) > lround(secondEntity.position.y))) {
|
||||
self.isBlockedFromUp = true;
|
||||
blockedFromUpBy = secondEntity;
|
||||
}
|
||||
}
|
||||
if ((lround(self.position.x - self.size.width+1) < lround(secondEntity.position.x))&&
|
||||
(lround(self.position.x + self.size.width-1) > (secondEntity.position.x))) {
|
||||
if ((lround(self.position.y - secondEntity.size.height-1) <= lround(secondEntity.position.y))&&
|
||||
(lround(self.position.y - secondEntity.size.height+1) >= lround(secondEntity.position.y))) {
|
||||
self.isBlockedFromDown = true;
|
||||
blockedFromDownBy = secondEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)checkCollisionWithRoomWithWidth:(CGFloat)roomWidth {
|
||||
if (lround(self.position.x) == 0) {
|
||||
self.isBlockedFromLeft = true;
|
||||
}
|
||||
if (lround(self.position.x) == lround(roomWidth - TILE_SIZE)) {
|
||||
self.isBlockedFromRight = true;
|
||||
}
|
||||
if (lround(self.position.y) == 0) {
|
||||
self.isBlockedFromDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)moveLeft {
|
||||
if (![self actionForKey:@"move"]) {
|
||||
SKAction *moveLeft = [SKAction moveByX:-TILE_SIZE y:0 duration: (self.isBlockedFromLeft) ? 0.7 : 0.4];
|
||||
if ((!self.isBlockedFromLeft)||
|
||||
(!(self.blockedFromRightBy.isBlockedFromLeft)&&(!self.blockedFromRightBy.isBlockedFromUp))) {
|
||||
[self runAction:moveLeft withKey:@"move"];
|
||||
[self.blockedFromLeftBy runAction:moveLeft];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)moveRight {
|
||||
if (![self actionForKey:@"move"]) {
|
||||
SKAction *moveRight = [SKAction moveByX:+TILE_SIZE y:0 duration: (self.isBlockedFromRight) ? 0.7 : 0.4];
|
||||
if ((!self.isBlockedFromRight)||
|
||||
(!(self.blockedFromRightBy.isBlockedFromRight)&&(!self.blockedFromRightBy.isBlockedFromUp))) {
|
||||
[self runAction:moveRight withKey:@"move"];
|
||||
[self.blockedFromRightBy runAction:moveRight];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)fall {
|
||||
if (!self.isBlockedFromDown) {
|
||||
SKAction *fall = [SKAction moveByX:0 y:-TILE_SIZE*0.5 duration:0.1];
|
||||
SKAction *idle = [SKAction moveByX:0 y:0 duration:0.4];
|
||||
if ((![self actionForKey:@"fall"])&&(![self actionForKey:@"jump"])) {
|
||||
[self runAction:fall withKey:@"fall"];
|
||||
[self runAction:idle withKey:@"afterFallIdle"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)jump {
|
||||
if (self.isBlockedFromDown) {
|
||||
SKAction *jump = [SKAction moveByX:0 y:+TILE_SIZE*1.5 duration:0.15];
|
||||
SKAction *pauseAfterJump = [SKAction moveByX:0 y:0 duration:0.2];
|
||||
if (![self actionForKey:@"jump"]) {
|
||||
[self runAction:jump];
|
||||
[self runAction:pauseAfterJump withKey:@"jump"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
#import <SpriteKit/SpriteKit.h>
|
||||
#import "Entity.h"
|
||||
#import "Level.h"
|
||||
#import "sceneParam.c"
|
||||
|
||||
@interface GameScene : SKScene
|
||||
{
|
||||
Entity *player;
|
||||
NSMutableArray *boxes;
|
||||
SKSpriteNode *background;
|
||||
SKLabelNode *scoreLabel;
|
||||
SKLabelNode *levelLabel;
|
||||
CFTimeInterval lastUpdateTime;
|
||||
CFTimeInterval pauseBeforeBoxDrop;
|
||||
CFTimeInterval boxDropDelay;
|
||||
int score;
|
||||
NSMutableArray *levels;
|
||||
int currentLvl;
|
||||
BOOL godmode;
|
||||
SKLabelNode *godmodeLabel;
|
||||
}
|
||||
@property Entity *player;
|
||||
@property NSMutableArray *boxes;
|
||||
@property SKSpriteNode *background;
|
||||
@property SKLabelNode *scoreLabel;
|
||||
@property SKLabelNode *levelLabel;
|
||||
@property CFTimeInterval lastUpdateTime;
|
||||
@property CFTimeInterval pauseBeforeBoxDrop;
|
||||
@property CFTimeInterval boxDropDelay;
|
||||
@property int score;
|
||||
@property NSMutableArray *levels;
|
||||
@property int currentLvl;
|
||||
@property BOOL godmode;
|
||||
@property SKLabelNode *godmodeLabel;
|
||||
|
||||
-(void)backGrInit;
|
||||
-(void)playerInit;
|
||||
-(void)scoreLabelInit;
|
||||
-(void)levelLabelInit;
|
||||
-(void)godmodeLabelInit;
|
||||
|
||||
-(void)newGame;
|
||||
-(void)newBox;
|
||||
-(int)getRandomNumberBetween:(int)start and:(int)end;
|
||||
-(void)checkForPlayerIsBlockedBy:(Entity *) checkedBox;
|
||||
-(void)checkForFullLine;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,249 @@
|
||||
#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
|
||||
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>RUSlan.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 RUSlan. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Level : NSObject
|
||||
{
|
||||
int goal, delayDec;
|
||||
}
|
||||
@property int goal, delayDec;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,7 @@
|
||||
#import "Level.h"
|
||||
|
||||
@implementation Level
|
||||
|
||||
@synthesize goal, delayDec;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// main.m
|
||||
// BoxAttack
|
||||
//
|
||||
// Created by RUSlan on 29.09.14.
|
||||
// Copyright (c) 2014 RUSlan. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#define TILE_SIZE 64
|
||||
#define NUMBER_OF_LVLS 5
|
||||
Reference in New Issue
Block a user