This repository has been archived by the owner on Jan 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
player.c
107 lines (96 loc) · 3.02 KB
/
player.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include "draw.h"
#include "game.h"
#include "init.h"
#include "main.h"
#include "player.h"
#define PLAYER_SPRITESHEET_WIDTH 35
#define PLAYER_SPRITESHEET_HEIGHT 35
#define PLAYER_SPRITESHEET_STRIDE 8
#define PLAYER_SPRITESHEET_COUNT 16
#define PLAYER_ROLL_SCALE 0.015f
#define PLAYER_BLINK_FRAME_OFFSET 16
#define PLAYER_BLINK_FRAMES 200
#define PLAYER_BLINK_INTERVAL_FRAMES ((rand() % 500) + 500)
#define PLAYER_BLINK_CHANCE 50
SDL_Surface* PlayerSpritesheet = NULL;
void PlayerUpdate(struct Player *player)
{
// Update the ball scroll.
player->Y += FIELD_SCROLL / 1000;
// Update the speed at which the player is going.
player->SpeedX += ((float) player->AccelX / 32767.0f) * ACCELERATION / 1000;
// Update the player's position and speed.
// Left and right edges (X). If the horizontal speed would run the
// ball into an edge, use up some of the energy in the impact and
// rebound the ball.
if (player->SpeedX < 0 && player->X - PLAYER_SIZE / 2 + player->SpeedX / 1000 < 0)
{
player->X = PLAYER_SIZE / 2
+ ((player->X - PLAYER_SIZE / 2) - (player->SpeedX / 1000)) * FIELD_REBOUND;
player->SpeedX = -player->SpeedX * FIELD_REBOUND;
}
else if (player->SpeedX > 0 && player->X + PLAYER_SIZE / 2 + player->SpeedX / 1000 > FIELD_WIDTH)
{
player->X = FIELD_WIDTH - PLAYER_SIZE / 2
+ (FIELD_WIDTH - (player->X + PLAYER_SIZE / 2) - (player->SpeedX / 1000)) * FIELD_REBOUND;
player->SpeedX = -player->SpeedX * FIELD_REBOUND;
}
else
{
player->X += player->SpeedX / 1000;
}
// Update roll animation based on speed
player->Roll += player->SpeedX * PLAYER_ROLL_SCALE;
if (player->Roll < 0)
{
player->Roll += PLAYER_SPRITESHEET_COUNT;
}
else if (player->Roll >= PLAYER_SPRITESHEET_COUNT)
{
player->Roll -= PLAYER_SPRITESHEET_COUNT;
}
// Randomly blink after not blinking for a while
player->BlinkCounter--;
player->NextBlinkCounter--;
if (player->NextBlinkCounter <= 0)
{
player->BlinkCounter = PLAYER_BLINK_FRAMES;
player->NextBlinkCounter = PLAYER_BLINK_INTERVAL_FRAMES;
}
}
void PlayerDraw(const struct Player *player)
{
// Draw the character.
int rollFrame = (int)floor(player->Roll);
if (player->BlinkCounter > 0)
{
rollFrame += PLAYER_BLINK_FRAME_OFFSET;
}
SDL_Rect src = {
(rollFrame % PLAYER_SPRITESHEET_STRIDE) * PLAYER_SPRITESHEET_WIDTH,
(rollFrame / PLAYER_SPRITESHEET_STRIDE) * PLAYER_SPRITESHEET_HEIGHT,
PLAYER_SPRITESHEET_WIDTH,
PLAYER_SPRITESHEET_HEIGHT
};
SDL_Rect dest = {
(int) roundf(player->X * SCREEN_WIDTH / FIELD_WIDTH) - (PLAYER_SPRITESHEET_WIDTH / 2),
(int) roundf(SCREEN_HEIGHT - player->Y * SCREEN_HEIGHT / FIELD_HEIGHT) - (PLAYER_SPRITESHEET_HEIGHT / 2),
0,
0
};
SDL_BlitSurface(PlayerSpritesheet, &src, Screen, &dest);
}
void PlayerReset(struct Player *player)
{
player->X = FIELD_WIDTH / 2;
player->Y = FIELD_HEIGHT - PLAYER_SIZE / 2;
player->SpeedX = 0.0f;
player->SpeedY = GRAVITY / 200 - FIELD_SCROLL / 200;
player->AccelX = 0;
player->Roll = 0.0f;
player->BlinkCounter = 0;
player->NextBlinkCounter = 1;
}