added sound to pong and fixed some bugs

This commit is contained in:
Jeena Paradies 2011-03-06 05:25:35 +01:00
parent c7919309e9
commit ac4036dfc8
15 changed files with 1373 additions and 111 deletions

View file

@ -11,7 +11,7 @@
@implementation GGSNetwork @implementation GGSNetwork
#define GGS_HOST @"localhost" #define GGS_HOST @"home.jeena.net"
#define GGS_PORT 9000 #define GGS_PORT 9000
#define NO_TIMEOUT -1 #define NO_TIMEOUT -1
@ -37,6 +37,7 @@
asyncSocket = [[AsyncSocket alloc] initWithDelegate:self]; asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
[asyncSocket connectToHost:GGS_HOST onPort:GGS_PORT error:nil]; [asyncSocket connectToHost:GGS_HOST onPort:GGS_PORT error:nil];
[asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:HEAD]; [asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:HEAD];
} }
@ -61,12 +62,11 @@
} }
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
} }
- (void)onSocket:(AsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag { - (void)onSocket:(AsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag {
if (tag == HEAD) { if (tag == HEAD) {
[self parseAndSetHeader:data]; [self parseAndSetHeader:data];

View file

@ -57,6 +57,7 @@
/* /*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/ */
[(PongViewController *)viewController restart];
} }

View file

@ -9,6 +9,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "GGSDelegate.h" #import "GGSDelegate.h"
#import "GGSNetwork.h" #import "GGSNetwork.h"
#import <AVFoundation/AVAudioPlayer.h>
enum GameType { enum GameType {
kGameTypeSinglePlayer = 0, kGameTypeSinglePlayer = 0,
@ -28,6 +29,11 @@ enum GameType {
IBOutlet UILabel *pointsP2; IBOutlet UILabel *pointsP2;
GGSNetwork *ggsNetwork; GGSNetwork *ggsNetwork;
AVAudioPlayer *pingSound;
AVAudioPlayer *pongSound;
AVAudioPlayer *lostSound;
} }
@property (nonatomic, retain) IBOutlet UIView *ballView; @property (nonatomic, retain) IBOutlet UIView *ballView;
@ -40,6 +46,8 @@ enum GameType {
@property (nonatomic, retain) GGSNetwork *ggsNetwork; @property (nonatomic, retain) GGSNetwork *ggsNetwork;
- (void)restart;
- (void)startPositions; - (void)startPositions;
- (void)zeroPoints; - (void)zeroPoints;

View file

@ -7,7 +7,6 @@
// //
#import "PongViewController.h" #import "PongViewController.h"
#import "GGSNetwork.h"
@implementation PongViewController @implementation PongViewController
@ -18,8 +17,8 @@
#define WIDTH 480 #define WIDTH 480
#define HEIGHT 320 #define HEIGHT 320
#define TOX(x) ( WIDTH / 100 * (x)) #define TOX(x) ( 4.8 * x )
#define TOY(y) ( HEIGHT / 100 * (y)) #define TOY(y) ( 3.2 * y )
@synthesize ballView, player1View, player2View, tapToBegin, pointsP1, pointsP2, ggsNetwork; @synthesize ballView, player1View, player2View, tapToBegin, pointsP1, pointsP2, ggsNetwork;
@ -49,32 +48,90 @@
#pragma mark GGSNetwork Delegate #pragma mark GGSNetwork Delegate
- (void)GGSNetwork:(GGSNetwork *)_ggsNetwork ready:(BOOL)ready { - (void)GGSNetwork:(GGSNetwork *)_ggsNetwork ready:(BOOL)ready {
[ggsNetwork define:@"function playerCommand(user, command, args) { user.sendCommand(command, args); }"]; [ggsNetwork sendCommand:@"ready" withArgs:@""];
} }
- (void)GGSNetwork:(GGSNetwork *)_ggsNetwork defined:(BOOL)defined { - (void)GGSNetwork:(GGSNetwork *)_ggsNetwork defined:(BOOL)defined {
if (defined) { // do nothing.
[ggsNetwork sendCommand:@"ready" withArgs:@""];
} else {
NSLog(@"Not defined");
}
} }
- (void)GGSNetwork:(GGSNetwork *)_ggsNetwork receivedCommand:(NSString *)command withArgs:(NSString *)args { - (void)GGSNetwork:(GGSNetwork *)_ggsNetwork receivedCommand:(NSString *)command withArgs:(NSString *)args {
NSLog(@"Command: %@; Args: %@", command, args);
if ([command isEqualToString:@"ball"]) { if ([command isEqualToString:@"ball"]) {
NSArray *ball = [args componentsSeparatedByString:@","]; NSArray *ball = [args componentsSeparatedByString:@","];
ballView.center = CGPointMake([[ball objectAtIndex:0] intValue], [[ball objectAtIndex:1] intValue]); [UIView beginAnimations:NULL context:NULL];
CGFloat x = [[ball objectAtIndex:0] floatValue];
CGFloat y = [[ball objectAtIndex:1] floatValue];
ballView.center = CGPointMake(TOX(x), TOY(y));
[UIView commitAnimations];
} else if ([command isEqualToString:@"player1_y"]) { } else if ([command isEqualToString:@"player1_y"]) {
player1View.center = CGPointMake(20, TOY([args intValue]));
[UIView beginAnimations:NULL context:NULL];
player1View.center = CGPointMake(25, TOY([args floatValue]));
[UIView commitAnimations];
} else if ([command isEqualToString:@"player2_y"]) { } else if ([command isEqualToString:@"player2_y"]) {
player2View.center = CGPointMake(WIDTH - 40, TOY([args intValue]));
[UIView beginAnimations:NULL context:NULL];
player2View.center = CGPointMake(WIDTH - 35, TOY([args floatValue]));
[UIView commitAnimations];
} else if ([command isEqualToString:@"player1_points"]) { } else if ([command isEqualToString:@"player1_points"]) {
pointsP1.text = args; pointsP1.text = args;
gamePaused = YES;
[lostSound play];
} else if ([command isEqualToString:@"player2_points"]) { } else if ([command isEqualToString:@"player2_points"]) {
pointsP2.text = args; pointsP2.text = args;
gamePaused = YES;
[lostSound play];
} else if ([command isEqualToString:@"game"]) {
if ([args isEqualToString:@"wait"]) {
NSLog(@"Other ready");
} else if ([args isEqualToString:@"start"]) {
gamePaused = NO;
}
} else if ([command isEqualToString:@"welcome"]) {
if ([args isEqualToString:@"1"]) {
player1View.backgroundColor = [UIColor redColor];
} else {
player2View.backgroundColor = [UIColor redColor];
}
} else if ([command isEqualToString:@"sound"]) {
if ([args isEqualToString:@"ping"]) {
[pingSound play];
} else {
[pongSound play];
}
}
}
#pragma mark -
#pragma mark Input
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (gamePaused) {
[ggsNetwork sendCommand:@"start" withArgs:@""];
tapToBegin.hidden = YES;
} else {
CGPoint point = [[[touches allObjects] objectAtIndex:0] locationInView:self.view];
if (point.y > (HEIGHT / 2)) {
[ggsNetwork sendCommand:@"down" withArgs:@""];
} else {
[ggsNetwork sendCommand:@"up" withArgs:@""];
}
} }
} }
@ -82,12 +139,35 @@
#pragma mark - #pragma mark -
#pragma mark View #pragma mark View
- (void)restart {
player1View.backgroundColor = [UIColor whiteColor];
player2View.backgroundColor = [UIColor whiteColor];
pointsP1.text = @"0";
pointsP2.text = @"0";
self.ggsNetwork = [[GGSNetwork alloc] initWithDelegate:self];
gamePaused = YES;
tapToBegin.hidden = NO;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
ggsNetwork = [[GGSNetwork alloc] initWithDelegate:self]; NSString *path = [[NSBundle mainBundle] pathForResource:@"ping" ofType:@"wav"];
pingSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[pingSound play];
path = [[NSBundle mainBundle] pathForResource:@"pong" ofType:@"wav"];
pongSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[pongSound play];
path = [[NSBundle mainBundle] pathForResource:@"lost" ofType:@"wav"];
lostSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[lostSound play];
//ggsNetwork = [[GGSNetwork alloc] initWithDelegate:self];
gamePaused = YES; gamePaused = YES;
//[self startPositions]; //[self startPositions];
//[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(moveBall) userInfo:nil repeats:YES]; //[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(moveBall) userInfo:nil repeats:YES];
@ -254,6 +334,10 @@
[pointsP2 release]; [pointsP2 release];
[ggsNetwork release]; [ggsNetwork release];
[pingSound release];
[pongSound release];
[lostSound release];
[super dealloc]; [super dealloc];
} }

View file

@ -326,19 +326,19 @@
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>1F369E7B1323081C004E7A99</string> <string>1F36A0221323417E004E7A99</string>
<key>history</key> <key>history</key>
<array> <array>
<string>1FBEBF151319F5C1006D5497</string> <string>1FBEBF151319F5C1006D5497</string>
<string>1FBEC001131AA71C006D5497</string> <string>1FBEC001131AA71C006D5497</string>
<string>1FBEC002131AA71C006D5497</string> <string>1FBEC002131AA71C006D5497</string>
<string>1FBEC05C131B085D006D5497</string> <string>1FBEC05C131B085D006D5497</string>
<string>1FBEC05D131B085D006D5497</string> <string>1F369ED81323101D004E7A99</string>
<string>1F369E761323081C004E7A99</string> <string>1F369F33132317A8004E7A99</string>
<string>1F369E771323081C004E7A99</string> <string>1F369F6C13232750004E7A99</string>
<string>1F369E781323081C004E7A99</string> <string>1F369FE61323395B004E7A99</string>
<string>1F369E791323081C004E7A99</string> <string>1F36A0201323417E004E7A99</string>
<string>1F369E7A1323081C004E7A99</string> <string>1F36A0211323417E004E7A99</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -536,7 +536,7 @@
<integer>5</integer> <integer>5</integer>
<key>WindowOrderList</key> <key>WindowOrderList</key>
<array> <array>
<string>1F369E861323081C004E7A99</string> <string>1F369E8E13230953004E7A99</string>
<string>1F369E871323081C004E7A99</string> <string>1F369E871323081C004E7A99</string>
<string>1CD10A99069EF8BA00B06720</string> <string>1CD10A99069EF8BA00B06720</string>
<string>1FA056A412F0B540003F1373</string> <string>1FA056A412F0B540003F1373</string>
@ -665,8 +665,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {316, 201}}</string> <string>{{0, 0}, {357, 449}}</string>
<string>{{316, 0}, {378, 201}}</string> <string>{{357, 0}, {428, 449}}</string>
</array> </array>
</dict> </dict>
<key>VerticalSplitView</key> <key>VerticalSplitView</key>
@ -681,8 +681,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {694, 201}}</string> <string>{{0, 0}, {785, 449}}</string>
<string>{{0, 201}, {694, 180}}</string> <string>{{0, 449}, {785, 403}}</string>
</array> </array>
</dict> </dict>
</dict> </dict>
@ -702,7 +702,7 @@
<key>DebugSTDIOWindowFrame</key> <key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string> <string>{{200, 200}, {500, 300}}</string>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {694, 381}}</string> <string>{{0, 0}, {785, 852}}</string>
<key>PBXDebugSessionStackFrameViewKey</key> <key>PBXDebugSessionStackFrameViewKey</key>
<dict> <dict>
<key>DebugVariablesTableConfiguration</key> <key>DebugVariablesTableConfiguration</key>
@ -712,24 +712,24 @@
<string>Value</string> <string>Value</string>
<real>85</real> <real>85</real>
<string>Summary</string> <string>Summary</string>
<real>148</real> <real>198</real>
</array> </array>
<key>Frame</key> <key>Frame</key>
<string>{{316, 0}, {378, 201}}</string> <string>{{357, 0}, {428, 449}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>108 977 694 422 0 0 2560 1418 </string> <string>108 506 785 893 0 0 2560 1418 </string>
</dict> </dict>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>108 977 694 422 0 0 2560 1418 </string> <string>108 506 785 893 0 0 2560 1418 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXDebugSessionModule</string> <string>PBXDebugSessionModule</string>
<key>Proportion</key> <key>Proportion</key>
<string>381pt</string> <string>852pt</string>
</dict> </dict>
</array> </array>
<key>Proportion</key> <key>Proportion</key>
<string>381pt</string> <string>852pt</string>
</dict> </dict>
</array> </array>
<key>Name</key> <key>Name</key>
@ -754,7 +754,7 @@
<key>ToolbarConfiguration</key> <key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string> <string>xcode.toolbar.config.debugV3</string>
<key>WindowString</key> <key>WindowString</key>
<string>108 977 694 422 0 0 2560 1418 </string> <string>108 506 785 893 0 0 2560 1418 </string>
<key>WindowToolGUID</key> <key>WindowToolGUID</key>
<string>1CD10A99069EF8BA00B06720</string> <string>1CD10A99069EF8BA00B06720</string>
<key>WindowToolIsVisible</key> <key>WindowToolIsVisible</key>
@ -880,18 +880,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {673, 481}}</string> <string>{{0, 0}, {724, 358}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>3600 653 673 522 2560 0 1920 1200 </string> <string>3598 801 724 399 2560 0 1920 1200 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXDebugCLIModule</string> <string>PBXDebugCLIModule</string>
<key>Proportion</key> <key>Proportion</key>
<string>481pt</string> <string>358pt</string>
</dict> </dict>
</array> </array>
<key>Proportion</key> <key>Proportion</key>
<string>481pt</string> <string>358pt</string>
</dict> </dict>
</array> </array>
<key>Name</key> <key>Name</key>
@ -911,7 +911,7 @@
<key>ToolbarConfiguration</key> <key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.consoleV3</string> <string>xcode.toolbar.config.consoleV3</string>
<key>WindowString</key> <key>WindowString</key>
<string>3600 653 673 522 2560 0 1920 1200 </string> <string>3598 801 724 399 2560 0 1920 1200 </string>
<key>WindowToolGUID</key> <key>WindowToolGUID</key>
<string>1C78EAAD065D492600B07095</string> <string>1C78EAAD065D492600B07095</string>
<key>WindowToolIsVisible</key> <key>WindowToolIsVisible</key>

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,10 @@
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
1F369FF813233C1E004E7A99 /* lost.wav in Resources */ = {isa = PBXBuildFile; fileRef = 1F369FF513233C1E004E7A99 /* lost.wav */; };
1F369FF913233C1E004E7A99 /* ping.wav in Resources */ = {isa = PBXBuildFile; fileRef = 1F369FF613233C1E004E7A99 /* ping.wav */; };
1F369FFA13233C1E004E7A99 /* pong.wav in Resources */ = {isa = PBXBuildFile; fileRef = 1F369FF713233C1E004E7A99 /* pong.wav */; };
1F36A00713233CCC004E7A99 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F36A00613233CCC004E7A99 /* AVFoundation.framework */; };
1FBEBF481319FC56006D5497 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FBEBF471319FC56006D5497 /* CFNetwork.framework */; }; 1FBEBF481319FC56006D5497 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FBEBF471319FC56006D5497 /* CFNetwork.framework */; };
1FBEBF4D1319FCDE006D5497 /* AsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBEBF4C1319FCDE006D5497 /* AsyncSocket.m */; }; 1FBEBF4D1319FCDE006D5497 /* AsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBEBF4C1319FCDE006D5497 /* AsyncSocket.m */; };
1FBEBFEF131A97F8006D5497 /* GGSNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBEBFEE131A97F8006D5497 /* GGSNetwork.m */; }; 1FBEBFEF131A97F8006D5497 /* GGSNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBEBFEE131A97F8006D5497 /* GGSNetwork.m */; };
@ -26,6 +30,10 @@
1D3623250D0F684500981E51 /* PongAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PongAppDelegate.m; sourceTree = "<group>"; }; 1D3623250D0F684500981E51 /* PongAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PongAppDelegate.m; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* Pong.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Pong.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D6058910D05DD3D006BFB54 /* Pong.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Pong.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
1F369FF513233C1E004E7A99 /* lost.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = lost.wav; sourceTree = "<group>"; };
1F369FF613233C1E004E7A99 /* ping.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ping.wav; sourceTree = "<group>"; };
1F369FF713233C1E004E7A99 /* pong.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = pong.wav; sourceTree = "<group>"; };
1F36A00613233CCC004E7A99 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
1FBEBF471319FC56006D5497 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; 1FBEBF471319FC56006D5497 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
1FBEBF4B1319FCDE006D5497 /* AsyncSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncSocket.h; sourceTree = "<group>"; }; 1FBEBF4B1319FCDE006D5497 /* AsyncSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncSocket.h; sourceTree = "<group>"; };
1FBEBF4C1319FCDE006D5497 /* AsyncSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsyncSocket.m; sourceTree = "<group>"; }; 1FBEBF4C1319FCDE006D5497 /* AsyncSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsyncSocket.m; sourceTree = "<group>"; };
@ -51,6 +59,7 @@
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
1FBEBF481319FC56006D5497 /* CFNetwork.framework in Frameworks */, 1FBEBF481319FC56006D5497 /* CFNetwork.framework in Frameworks */,
1F36A00713233CCC004E7A99 /* AVFoundation.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -115,6 +124,9 @@
children = ( children = (
2899E5210DE3E06400AC0155 /* PongViewController.xib */, 2899E5210DE3E06400AC0155 /* PongViewController.xib */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */, 28AD733E0D9D9553002E5188 /* MainWindow.xib */,
1F369FF513233C1E004E7A99 /* lost.wav */,
1F369FF613233C1E004E7A99 /* ping.wav */,
1F369FF713233C1E004E7A99 /* pong.wav */,
8D1107310486CEB800E47090 /* Pong-Info.plist */, 8D1107310486CEB800E47090 /* Pong-Info.plist */,
); );
name = Resources; name = Resources;
@ -127,6 +139,7 @@
1D30AB110D05D00D00671497 /* Foundation.framework */, 1D30AB110D05D00D00671497 /* Foundation.framework */,
288765A40DF7441C002DB57D /* CoreGraphics.framework */, 288765A40DF7441C002DB57D /* CoreGraphics.framework */,
1FBEBF471319FC56006D5497 /* CFNetwork.framework */, 1FBEBF471319FC56006D5497 /* CFNetwork.framework */,
1F36A00613233CCC004E7A99 /* AVFoundation.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -182,6 +195,9 @@
files = ( files = (
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
2899E5220DE3E06400AC0155 /* PongViewController.xib in Resources */, 2899E5220DE3E06400AC0155 /* PongViewController.xib in Resources */,
1F369FF813233C1E004E7A99 /* lost.wav in Resources */,
1F369FF913233C1E004E7A99 /* ping.wav in Resources */,
1F369FFA13233C1E004E7A99 /* pong.wav in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

BIN
games/Pong/lost.wav Normal file

Binary file not shown.

BIN
games/Pong/ping.wav Normal file

Binary file not shown.

BIN
games/Pong/pong.wav Normal file

Binary file not shown.

View file

@ -102,7 +102,6 @@ init([]) ->
handle_call(join_lobby, From, State) -> handle_call(join_lobby, From, State) ->
Token = helpers:get_new_token(), Token = helpers:get_new_token(),
Players = State#co_state.players, Players = State#co_state.players,
io:format("join_lobby from: ~p~n", [From]),
{Pid, _Sock} = From, {Pid, _Sock} = From,
NewState = State#co_state{players = [{Pid, Token} | Players]}, NewState = State#co_state{players = [{Pid, Token} | Players]},
back_up(NewState), back_up(NewState),

View file

@ -191,8 +191,9 @@ intern_start(Table, Player) ->
true -> true ->
ggs_table:notify_all_players(Table, {"game", "start"}), ggs_table:notify_all_players(Table, {"game", "start"}),
ggs_db:setItem(Table, local_storage, ball, {50,50,1,1}), ggs_db:setItem(Table, local_storage, ball, {50,50,1,1}),
spawn(fun() -> game_loop([Table]) end); Pid = spawn(fun() -> game_loop([Table]) end),
false -> Pid ! tick;
_Other ->
ggs_table:send_command(Table, Player, {"game", "wait"}) ggs_table:send_command(Table, Player, {"game", "wait"})
end; end;
player2 -> player2 ->
@ -202,8 +203,9 @@ intern_start(Table, Player) ->
true -> true ->
ggs_table:notify_all_players(Table, {"game", "start"}), ggs_table:notify_all_players(Table, {"game", "start"}),
ggs_db:setItem(Table, local_storage, ball, {50,50,-1,-1}), ggs_db:setItem(Table, local_storage, ball, {50,50,-1,-1}),
spawn(fun() -> game_loop([Table]) end); GameLoop = spawn(fun() -> game_loop([Table]) end),
false -> GameLoop ! tick;
_Other ->
ggs_table:send_command(Table, Player, {"game", "wait"}) ggs_table:send_command(Table, Player, {"game", "wait"})
end end
end. end.
@ -215,18 +217,19 @@ game_loop([Table]) ->
Ball = {BX, BY, SX, SY}, Ball = {BX, BY, SX, SY},
ggs_db:setItem(Table, local_storage, ball, Ball), ggs_db:setItem(Table, local_storage, ball, Ball),
ggs_table:notify_all_players(Table, {"ball", int2str(BX) ++ "," ++ int2str(BY)}), ggs_table:notify_all_players(Table, {"ball", int2str(BX) ++ "," ++ int2str(BY)}),
check_ball(Table, Ball); check_ball(Table, Ball),
timer:send_after(50, tick),
game_loop([Table]);
'EXIT' -> 'EXIT' ->
exit(normal) exit(normal)
after 5000 ->
self() ! tick
end. end.
int2str(Int) -> int2str(Int) ->
lists:flatten(io_lib:format("~p", [Int])). lists:flatten(io_lib:format("~p", [Int])).
step_ball({BX, BY, SX, SY}) -> step_ball({BX, BY, SX, SY}) ->
{BX + SX, BY + SY, SX, BY}. Ball = {BX + SX, BY + SY, SX, SY},
Ball.
check_ball(Table, {BX, BY, SX, SY}) -> check_ball(Table, {BX, BY, SX, SY}) ->
% check up and down bounds % check up and down bounds
@ -237,43 +240,52 @@ check_ball(Table, {BX, BY, SX, SY}) ->
NewSY = SY NewSY = SY
end, end,
% check intersection with player1 % check intersection with a player
P1Y = ggs_db:getItem(Table, local_storage, player1_y), P1Y = ggs_db:getItem(Table, local_storage, player1_y),
case check_intersect({0, P1Y, 10, 30}, {BX, BY, 10, 10}) of
true ->
SX1 = -SX;
false ->
SX1 = SX
end,
% check intersection with player2
P2Y = ggs_db:getItem(Table, local_storage, player2_y), P2Y = ggs_db:getItem(Table, local_storage, player2_y),
case check_intersect({90, P2Y, 10, 30}, {BX, BY, 10, 10}) of case (check_intersect({0, P1Y, 10, 30}, {BX, BY, 10, 10}) or check_intersect({99, P2Y, 10, 30}, {BX, BY, 10, 10})) of
true -> true ->
SX2 = - SX1; NewSX = -SX,
case NewSX of
-1 ->
ggs_table:notify_all_players(Table, {"sound", "ping"});
1 ->
ggs_table:notify_all_players(Table, {"sound", "pong"})
end;
false -> false ->
SX2 = SX1 NewSX = SX
end, end,
ggs_db:setItem(Table, local_storage, ball, {BX, BY , SX2, NewSY}), ggs_db:setItem(Table, local_storage, ball, {BX, BY , NewSX, NewSY}),
% check for point player1 % check for point player1
if BX > 90 -> case BX > 100 of
Player1Points = ggs_db:getItem(Table, local_storage, player1_points), true ->
NewPlayer1Points = Player1Points + 1, Player1Points = ggs_db:getItem(Table, local_storage, player1_points),
ggs_db:setItem(Table, local_storage, player1_points, NewPlayer1Points), NewPlayer1Points = Player1Points + 1,
ggs_table:notify_all_players(Table, {"player1_points", int2str(NewPlayer1Points)}), ggs_db:setItem(Table, local_storage, player1_points, NewPlayer1Points),
exit(normal) ggs_table:notify_all_players(Table, {"player1_points", int2str(NewPlayer1Points)}),
exit(normal);
false ->
ok
end, end,
% check for point player2 % check for point player2
if BX < 0 -> case BX < 0 of
Player2Points = ggs_db:getItem(Table, local_storage, player2_points), true ->
NewPlayer2Points = Player2Points + 1, Player2Points = ggs_db:getItem(Table, local_storage, player2_points),
ggs_db:setItem(Table, local_storage, player2_points, NewPlayer2Points), NewPlayer2Points = Player2Points + 1,
ggs_table:notify_all_players(Table, {"player2_points", int2str(NewPlayer2Points)}), ggs_db:setItem(Table, local_storage, player2_points, NewPlayer2Points),
exit(normal) ggs_table:notify_all_players(Table, {"player2_points", int2str(NewPlayer2Points)}),
exit(normal);
false ->
ok
end. end.
check_intersect({AX, AY, AW, AH}, {BX, BY, BW, BH}) -> check_intersect({AX1, AY1, AW, AH}, {BX1, BY1, BW, BH}) ->
not (BX > (AX + AW)) or ((BX + BW) < AX) or (BY > (AY + AH)) or ((BY + BH) < AY). AX2 = AX1 + AW,
AY2 = AY1 + AH,
BX2 = BX1 + BW,
BY2 = BY1 + BH,
(AX1 < BX2) and (AX2 > BX1) and (AY1 < BY2) and (AY2 > BY1).

View file

@ -40,7 +40,6 @@ start_link(Socket) ->
%% @spec notify(Player::Pid(), From::Pid(), %% @spec notify(Player::Pid(), From::Pid(),
%% {Command::String(), Message::string()}) -> ok %% {Command::String(), Message::string()}) -> ok
notify(Player, From, Message) -> notify(Player, From, Message) ->
erlang:display(Message),
{Cmd, Data} = Message, {Cmd, Data} = Message,
Parsed = ggs_protocol:create_message(Cmd, "text","text", Data), Parsed = ggs_protocol:create_message(Cmd, "text","text", Data),
Player ! {notify, From, Parsed}. Player ! {notify, From, Parsed}.
@ -62,14 +61,10 @@ stop(_Player,_Table) ->
loop(#pl_state{token = _Token, socket = Socket, table = Table} = State) -> loop(#pl_state{token = _Token, socket = Socket, table = Table} = State) ->
receive receive
{tcp, Socket, Data} -> % Just echo for now.. {tcp, Socket, Data} -> % Just echo for now..
io:format("Parsing via protocol module..~n"),
erlang:display(Data),
Parsed = ggs_protocol:parse(Data), Parsed = ggs_protocol:parse(Data),
erlang:display(Parsed),
self() ! Parsed, self() ! Parsed,
loop(State); loop(State);
{notify, _From, Message} -> {notify, _From, Message} ->
erlang:display(Message),
gen_tcp:send(Socket, Message), gen_tcp:send(Socket, Message),
loop(State); loop(State);
% Below are messages generated by the parser % Below are messages generated by the parser

View file

@ -44,7 +44,6 @@ remove_player(Table, Player) ->
%% @doc Get a list of all player processes attached to this table %% @doc Get a list of all player processes attached to this table
get_player_list(TableToken) -> get_player_list(TableToken) ->
TablePid = ggs_coordinator:table_token_to_pid(TableToken), TablePid = ggs_coordinator:table_token_to_pid(TableToken),
erlang:display(TablePid),
gen_server:call(TablePid, get_player_list). gen_server:call(TablePid, get_player_list).
% @doc stops the table process % @doc stops the table process
@ -88,7 +87,6 @@ handle_call({remove_player, Player}, _From, #state { players = Players } = State
{reply, ok, State#state { players = Players -- [Player] }}; {reply, ok, State#state { players = Players -- [Player] }};
handle_call(get_player_list, _From, #state { players = Players } = State) -> handle_call(get_player_list, _From, #state { players = Players } = State) ->
io:format("Players: ~p~n", [Players]),
TokenPlayers = lists:map( TokenPlayers = lists:map(
fun (Pid) -> ggs_coordinator:player_pid_to_token(Pid) end, Players), fun (Pid) -> ggs_coordinator:player_pid_to_token(Pid) end, Players),
{reply, {ok, TokenPlayers}, State}; {reply, {ok, TokenPlayers}, State};

26
tests/tick.erl Normal file
View file

@ -0,0 +1,26 @@
-module(tick).
-export([start/0]).
start() ->
spawn(fun() -> loop() end).
loop() ->
receive
tick ->
erlang:display("tick!"),
timer:send_after(500, tick),
loop();
'EXIT' ->
exit(normal)
end.
% 1> c(tick).
% {ok,tick}
% 2> Pid = tick:start().
% <0.38.0>
% % Nothing happens :-(
% When I send it myself then it responds
% 3> Pid ! tick.
% tick
% 5>