Skip to content

Commit 8d64f09

Browse files
committed
WIP two player
1 parent 9575f25 commit 8d64f09

File tree

12 files changed

+114
-75
lines changed

12 files changed

+114
-75
lines changed

camera.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@ void CameraInit(Camera *c)
3838
c->ScrollCounter = 0;
3939
}
4040

41-
void CameraUpdate(Camera *c, const Player *p, const uint32_t ms)
41+
void CameraUpdate(Camera *c, const float playerY, const uint32_t ms)
4242
{
4343
c->DY -= ms * c->ScrollRate / 1000;
44-
if (c->DY < p->Y)
44+
if (c->DY < playerY)
4545
{
4646
c->Y = c->DY;
4747
}
4848
else
4949
{
50-
c->Y = 0.8f * p->Y + 0.2f * c->DY;
50+
c->Y = 0.8f * playerY + 0.2f * c->DY;
5151
}
52-
c->DY = MIN(c->DY, p->Y + FIELD_HEIGHT / 2);
52+
c->DY = MIN(c->DY, playerY + FIELD_HEIGHT / 2);
5353
c->ScrollCounter += ms;
5454
if (c->ScrollCounter >= 1000)
5555
{
@@ -60,5 +60,5 @@ void CameraUpdate(Camera *c, const Player *p, const uint32_t ms)
6060
//printf("%f\n", c->ScrollRate);
6161
// Disable scrolling
6262
//printf("%f %f\n", c->DY, c->Y);
63-
//c->Y = p->Y;
63+
//c->Y =playerY;
6464
}

camera.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ POSSIBILITY OF SUCH DAMAGE.
2727

2828
#include <stdint.h>
2929

30-
#include "player.h"
31-
3230
typedef struct
3331
{
3432
float DY;
@@ -39,4 +37,4 @@ typedef struct
3937
extern Camera camera;
4038

4139
void CameraInit(Camera *c);
42-
void CameraUpdate(Camera *c, const Player *p, const uint32_t ms);
40+
void CameraUpdate(Camera *c, const float playerY, const uint32_t ms);

data/graphics/penguin_black.png

40.5 KB
Loading

game.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "camera.h"
3030
#include "main.h"
3131
#include "init.h"
32+
#include "input.h"
3233
#include "platform.h"
3334
#include "player.h"
3435
#include "sound.h"
@@ -45,6 +46,7 @@ static bool Boost;
4546
static bool Pause;
4647

4748
static Player player;
49+
static Player player2;
4850

4951
// What the player avoids.
5052
static struct Gap* Gaps = NULL;
@@ -70,7 +72,7 @@ void GameGatherInput(bool* Continue)
7072

7173
while (SDL_PollEvent(&ev))
7274
{
73-
player.AccelX = GetMovement(&ev);
75+
InputOnEvent(&ev);
7476
if (IsPauseEvent(&ev))
7577
Pause = !Pause;
7678
else if (IsExitGameEvent(&ev))
@@ -79,6 +81,8 @@ void GameGatherInput(bool* Continue)
7981
return;
8082
}
8183
}
84+
player.AccelX = GetMovement(0);
85+
player2.AccelX = GetMovement(1);
8286
}
8387

8488
static void AddEdgeShapes(const float y);
@@ -115,16 +119,17 @@ void GameDoLogic(bool* Continue, bool* Error, Uint32 Milliseconds)
115119
}
116120

117121
PlayerUpdate(&player);
118-
CameraUpdate(&camera, &player, Milliseconds);
119-
if (player.Y < edgeBodiesBottom)
122+
PlayerUpdate(&player2);
123+
CameraUpdate(&camera, (player.Y + player2.Y) / 2, Milliseconds);
124+
if (min(player.Y, player2.Y) < edgeBodiesBottom)
120125
{
121126
cpBodyEachShape(edgeBodies, RemoveEdgeShape, NULL);
122-
AddEdgeShapes(player.Y);
127+
AddEdgeShapes(min(player.Y, player2.Y));
123128
}
124129

125130
// If the ball has collided with the top of the field,
126131
// the player's game is over.
127-
if (player.Y + PLAYER_RADIUS >= camera.Y + FIELD_HEIGHT / 2)
132+
if (max(player.Y, player2.Y) + PLAYER_RADIUS >= camera.Y + FIELD_HEIGHT / 2)
128133
{
129134
ToScore(Score);
130135
}
@@ -145,7 +150,7 @@ static void ScoreGaps()
145150
}
146151
// Arbitrary limit to eliminate off screen gaps
147152
// If a gap is past the top side, remove it.
148-
if (GapBottom(&Gaps[i]) > player.Y + FIELD_HEIGHT * 2)
153+
if (GapBottom(&Gaps[i]) > max(player.Y, player2.Y) + FIELD_HEIGHT * 2)
149154
{
150155
GapRemove(&Gaps[i]);
151156
memmove(&Gaps[i], &Gaps[i + 1], (GapCount - i) * sizeof(struct Gap));
@@ -176,6 +181,7 @@ void GameOutputFrame(void)
176181
}
177182

178183
PlayerDraw(&player, screenYOff);
184+
PlayerDraw(&player2, screenYOff);
179185

180186
// Draw the player's current score.
181187
char ScoreString[17];
@@ -206,7 +212,8 @@ void ToGame(void)
206212
edgeBodies = cpSpaceGetStaticBody(Space);
207213
AddEdgeShapes(0);
208214

209-
PlayerInit(&player);
215+
PlayerInit(&player, 0);
216+
PlayerInit(&player2, 1);
210217
if (Gaps != NULL)
211218
{
212219
free(Gaps);

init.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ void Initialize(bool* Continue, bool* Error)
100100
LOAD_IMG(icon, "icon.png");
101101
SDL_WM_SetIcon(icon, NULL);
102102

103-
LOAD_IMG(PlayerSpritesheet, "penguin_ball.png");
103+
LOAD_IMG(PlayerSpritesheets[0], "penguin_ball.png");
104+
LOAD_IMG(PlayerSpritesheets[1], "penguin_black.png");
104105
LOAD_IMG(GameOverImages[0], "gameover_01.png");
105106
LOAD_IMG(GameOverImages[1], "gameover_02.png");
106107

@@ -170,7 +171,10 @@ void Initialize(bool* Continue, bool* Error)
170171
void Finalize()
171172
{
172173
cpSpaceFree(Space);
173-
SDL_FreeSurface(PlayerSpritesheet);
174+
for (int i = 0; i < MAX_PLAYERS; i++)
175+
{
176+
SDL_FreeSurface(PlayerSpritesheets[i]);
177+
}
174178
SDL_FreeSurface(GameOverImages[0]);
175179
SDL_FreeSurface(GameOverImages[1]);
176180
SDL_FreeSurface(icon);

input.c

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (C) 2014 Nebuleon Fumika <[email protected]>
3+
* 2015 Cong Xu <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License
7+
* as published by the Free Software Foundation; either version 2
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
#include "input.h"
20+
21+
#include <stdbool.h>
22+
23+
#define P1_LEFT SDLK_LEFT
24+
#define P1_RIGHT SDLK_RIGHT
25+
#define P2_LEFT SDLK_a
26+
#define P2_RIGHT SDLK_d
27+
28+
static bool pressed[SDLK_LAST];
29+
30+
void InputOnEvent(const SDL_Event* event)
31+
{
32+
if (event->type == SDL_KEYUP || event->type == SDL_KEYDOWN)
33+
{
34+
pressed[event->key.keysym.sym] = event->type == SDL_KEYDOWN;
35+
}
36+
}
37+
38+
int16_t GetMovement(const int player)
39+
{
40+
return pressed[player == 0 ? P1_LEFT : P2_LEFT]
41+
? (pressed[player == 0 ? P1_RIGHT : P2_RIGHT] ? 0 : -32768)
42+
: (pressed[player == 0 ? P1_RIGHT : P2_RIGHT] ? 32767 : 0);
43+
}
44+
45+
void ResetMovement(void)
46+
{
47+
memset(pressed, 0, sizeof pressed);
48+
}

input.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2014 Nebuleon Fumika <[email protected]>
3+
* 2015 Cong Xu <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License
7+
* as published by the Free Software Foundation; either version 2
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
#pragma once
20+
21+
#include <SDL.h>
22+
23+
void InputOnEvent(const SDL_Event* event);
24+
25+
// GetMovement returns, after updating the platform-specific input status, a
26+
// value between -32768 and +32767 to indicate how far the ball needs to go.
27+
// Negative values go to the left; positive values go to the right.
28+
int16_t GetMovement(const int player);
29+
void ResetMovement(void);

platform.h

-7
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ extern Uint32 ToNextFrame(void);
3636
// ExitGame: true if the event can be used to exit the entire application.
3737
// Pause: true if the event can be used to pause a game in progress.
3838

39-
// GetMovement returns, after updating the platform-specific input status, a
40-
// value between -32768 and +32767 to indicate how far the ball needs to go.
41-
// Negative values go to the left; positive values go to the right.
42-
4339
// Get???Prompt returns the text that can be used to describe the actions that
4440
// can trigger a feature on the platform.
4541

@@ -50,10 +46,7 @@ extern const char* GetEnterGamePrompt(void);
5046
extern bool IsExitGameEvent(const SDL_Event* event);
5147
extern const char* GetExitGamePrompt(void);
5248

53-
extern int16_t GetMovement(const SDL_Event* event);
5449
extern const char* GetMovementPrompt(void);
5550

5651
extern bool IsPauseEvent(const SDL_Event* event);
5752
extern const char* GetPausePrompt(void);
58-
59-
extern void ResetMovement(void);

platform/general.c

-22
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
#include "platform.h"
2626

2727
static Uint32 LastTicks = 0;
28-
static bool LeftPressed;
29-
static bool RightPressed;
3028

3129
void InitializePlatform(void)
3230
{
@@ -73,21 +71,6 @@ const char* GetExitGamePrompt(void)
7371
return "Esc";
7472
}
7573

76-
int16_t GetMovement(const SDL_Event* event)
77-
{
78-
if (event->type == SDL_KEYUP
79-
|| event->type == SDL_KEYDOWN)
80-
{
81-
if (event->key.keysym.sym == SDLK_LEFT)
82-
LeftPressed = event->type == SDL_KEYDOWN;
83-
else if (event->key.keysym.sym == SDLK_RIGHT)
84-
RightPressed = event->type == SDL_KEYDOWN;
85-
}
86-
return (LeftPressed)
87-
? ((RightPressed) ? 0 : -32768)
88-
: ((RightPressed) ? 32767 : 0);
89-
}
90-
9174
const char* GetMovementPrompt(void)
9275
{
9376
return "Left/Right";
@@ -103,8 +86,3 @@ const char* GetPausePrompt(void)
10386
{
10487
return "P";
10588
}
106-
107-
void ResetMovement(void)
108-
{
109-
LeftPressed = RightPressed = false;
110-
}

platform/opendingux.c

-23
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424

2525
#include "platform.h"
2626

27-
static bool LeftPressed;
28-
static bool RightPressed;
29-
3027
void InitializePlatform(void)
3128
{
3229
}
@@ -69,21 +66,6 @@ const char* GetExitGamePrompt(void)
6966
return "B/Select";
7067
}
7168

72-
int16_t GetMovement(const SDL_Event* event)
73-
{
74-
if (event->type == SDL_KEYUP
75-
|| event->type == SDL_KEYDOWN)
76-
{
77-
if (event->key.keysym.sym == SDLK_LEFT)
78-
LeftPressed = event->type == SDL_KEYDOWN;
79-
else if (event->key.keysym.sym == SDLK_RIGHT)
80-
RightPressed = event->type == SDL_KEYDOWN;
81-
}
82-
return (LeftPressed)
83-
? ((RightPressed) ? 0 : -32768)
84-
: ((RightPressed) ? 32767 : 0);
85-
}
86-
8769
const char* GetMovementPrompt(void)
8870
{
8971
return "D-pad Left/Right";
@@ -99,8 +81,3 @@ const char* GetPausePrompt(void)
9981
{
10082
return "Start";
10183
}
102-
103-
void ResetMovement(void)
104-
{
105-
LeftPressed = RightPressed = false;
106-
}

player.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#define PLAYER_BLINK_INTERVAL_FRAMES ((rand() % 500) + 500)
2121
#define PLAYER_BLINK_CHANCE 50
2222

23-
SDL_Surface* PlayerSpritesheet = NULL;
23+
SDL_Surface* PlayerSpritesheets[MAX_PLAYERS];
2424
Mix_Chunk* SoundPlayerBounce = NULL;
2525
Mix_Chunk* SoundPlayerRoll = NULL;
2626

@@ -40,7 +40,7 @@ void PlayerUpdate(Player *player)
4040
// - when the player is above max speed
4141
float accel = ACCELERATION;
4242
const cpVect vel = cpBodyGetVelocity(player->Body);
43-
const float relVelX = fabs(vel.x) * SIGN(vel.x * player->AccelX);
43+
const float relVelX = (float)fabs(vel.x) * SIGN(vel.x * player->AccelX);
4444
if (relVelX > MAX_SPEED) accel = ACCELERATION_MAX_SPEED;
4545
if (relVelX < MIN_SPEED) accel += MIN_SPEED_ACCEL_BONUS;
4646
if (player->WasOnSurface) accel += ROLL_ACCEL_BONUS;
@@ -115,10 +115,10 @@ void PlayerDraw(const Player *player, const float y)
115115
0,
116116
0
117117
};
118-
SDL_BlitSurface(PlayerSpritesheet, &src, Screen, &dest);
118+
SDL_BlitSurface(player->Sprites, &src, Screen, &dest);
119119
}
120120

121-
void PlayerInit(Player *player)
121+
void PlayerInit(Player *player, const int i)
122122
{
123123
player->Body = cpSpaceAddBody(
124124
Space,
@@ -138,4 +138,5 @@ void PlayerInit(Player *player)
138138
player->Roll = 0;
139139
player->BlinkCounter = 0;
140140
player->NextBlinkCounter = 1;
141+
player->Sprites = PlayerSpritesheets[i];
141142
}

player.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@ typedef struct
2727
int BlinkCounter;
2828
// Blink when counter reaches zero
2929
int NextBlinkCounter;
30+
31+
SDL_Surface *Sprites;
3032
} Player;
3133

32-
extern SDL_Surface* PlayerSpritesheet;
34+
#define MAX_PLAYERS 2
35+
36+
extern SDL_Surface* PlayerSpritesheets[MAX_PLAYERS];
3337
extern Mix_Chunk* SoundPlayerBounce;
3438
extern Mix_Chunk* SoundPlayerRoll;
3539
extern int SoundPlayerRollChannel;
3640

3741
void PlayerUpdate(Player *player);
3842
void PlayerDraw(const Player *player, const float y);
39-
void PlayerInit(Player *player);
43+
void PlayerInit(Player *player, const int i);

0 commit comments

Comments
 (0)