2 // C Implementation: player/tux
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
9 // Copyright: See COPYING file that comes with this distribution
20 texture_type tux_life,
21 tux_right[3], tux_left[3],
22 bigtux_right[3], bigtux_left[3],
23 bigtux_right_jump, bigtux_left_jump,
24 ducktux_right, ducktux_left,
25 skidtux_right, skidtux_left,
26 firetux_right[3], firetux_left[3],
27 bigfiretux_right[3], bigfiretux_left[3],
28 bigfiretux_right_jump, bigfiretux_left_jump,
29 duckfiretux_right, duckfiretux_left,
30 skidfiretux_right, skidfiretux_left,
31 cape_right[2], cape_left[2],
32 bigcape_right[2], bigcape_left[2];
34 void player_init(player_type* pplayer)
36 pplayer->base.width = 32;
37 pplayer->base.height = 32;
39 pplayer->size = SMALL;
40 pplayer->got_coffee = NO;
43 pplayer->base.y = 240;
50 pplayer->jumping = NO;
52 pplayer->frame_main = 0;
56 pplayer->input.down = UP;
57 pplayer->input.fire = UP;
58 pplayer->input.left = UP;
59 pplayer->input.old_fire = UP;
60 pplayer->input.right = UP;
61 pplayer->input.up = UP;
63 pplayer->keymap.jump = SDLK_UP;
64 pplayer->keymap.duck = SDLK_DOWN;
65 pplayer->keymap.left = SDLK_LEFT;
66 pplayer->keymap.right = SDLK_RIGHT;
67 pplayer->keymap.fire = SDLK_LCTRL;
69 timer_init(&pplayer->invincible_timer);
70 timer_init(&pplayer->skidding_timer);
71 timer_init(&pplayer->safe_timer);
74 int player_key_event(player_type* pplayer, SDLKey key, int state)
76 if(key == pplayer->keymap.right)
78 pplayer->input.right = state;
81 else if( key == pplayer->keymap.left)
83 pplayer->input.left = state;
86 else if(key == pplayer->keymap.jump)
88 pplayer->input.up = state;
91 else if(key == pplayer->keymap.duck)
93 pplayer->input.down = state;
96 else if(key == pplayer->keymap.fire)
98 pplayer->input.fire = state;
105 void player_level_begin(player_type* pplayer)
108 pplayer->base.y = 240;
109 pplayer->base.xm = 0;
110 pplayer->base.ym = 0;
112 pplayer->input.down = UP;
113 pplayer->input.fire = UP;
114 pplayer->input.left = UP;
115 pplayer->input.old_fire = UP;
116 pplayer->input.right = UP;
117 pplayer->input.up = UP;
119 timer_init(&pplayer->invincible_timer);
120 timer_init(&pplayer->skidding_timer);
121 timer_init(&pplayer->safe_timer);
124 void player_action(player_type* pplayer)
126 /* --- HANDLE TUX! --- */
128 player_input(pplayer);
132 pplayer->base.x= pplayer->base.x+ pplayer->base.xm * frame_ratio;
133 pplayer->base.y = pplayer->base.y + pplayer->base.ym * frame_ratio;
135 player_keep_in_bounds(pplayer);
141 /* FIXME: this code is COMPLETLY broken!!! */
142 /* if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
143 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
145 while (issolid(pplayer->base.x, pplayer->base.y + 31))
147 if (pplayer->base.xm < 0)
149 else if (pplayer->base.xm > 0)
153 pplayer->base.xm = 0;
156 /*if (issolid(pplayer->base.x, pplayer->base.y) &&
157 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
159 while (issolid(pplayer->base.x, (pplayer->base.y)))
161 if (pplayer->base.xm < 0)
163 else if (pplayer->base.xm > 0)
167 pplayer->base.xm = 0;
170 if (issolid(pplayer->base.x, pplayer->base.y + 31))
172 /* Set down properly: */
175 while (issolid(pplayer->base.x, pplayer->base.y + 31))
180 DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
181 /*the circumstances are:
182 issolid() is true and base.ym == 0
183 use of floating point varibles for base stuff*/
186 if (pplayer->base.ym < 0)
188 else if (pplayer->base.ym > 0)
193 /* Reset score multiplier (for multi-hits): */
195 if (pplayer->base.ym > 0)
196 score_multiplier = 1;
201 pplayer->base.ym = 0;
202 pplayer->jumping = NO;
203 pplayer->input.up = UP;
205 /* FIXME: this code is COMPLETLY broken!!! */
206 /*if (issolid(pplayer->base.x, pplayer->base.y) ||
207 (pplayer->size == BIG && !pplayer->duck &&
208 (issolid(pplayer->base.x, pplayer->base.y - 32))))
210 /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
211 (pplayer->size == SMALL || pplayer->duck ||
212 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))*/
214 if (((!issolid(pplayer->base.x, pplayer->base.y- pplayer->base.ym * frame_ratio) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x, pplayer->base.y+31))))
215 ||((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)))))
216 /*(pplayer->size == SMALL || pplayer->duck ||
217 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/
219 pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio;
220 pplayer->base.ym = 0;
223 if (((issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) && (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y))
224 /*(pplayer->size == SMALL || pplayer->duck ||
225 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/) ||
226 (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+pplayer->base.height) && (issolid(pplayer->base.x, pplayer->base.y+pplayer->base.height) || issolid(pplayer->base.x +32, pplayer->base.y+pplayer->base.height))))
228 pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio;
229 pplayer->base.xm = 0;
232 if (pplayer->base.ym <= 0)
234 if (isbrick(pplayer->base.x, pplayer->base.y) ||
235 isfullbox(pplayer->base.x, pplayer->base.y))
237 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
238 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
239 bumpbrick(pplayer->base.x, pplayer->base.y);
240 tryemptybox(pplayer->base.x, pplayer->base.y);
243 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
244 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
246 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
247 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
248 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
249 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
251 /* Get a distro from a brick? */
253 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
254 shape(pplayer->base.x, pplayer->base.y) == 'y')
256 add_bouncy_distro(((pplayer->base.x+ 1)
258 (int)(pplayer->base.y / 32) * 32);
260 if (counting_distros == NO)
262 counting_distros = YES;
263 distro_counter = 100;
266 if (distro_counter <= 0)
267 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
269 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
270 score = score + SCORE_DISTRO;
273 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
274 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
276 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
278 (int)(pplayer->base.y / 32) * 32);
280 if (counting_distros == NO)
282 counting_distros = YES;
283 distro_counter = 100;
286 if (distro_counter <= 0)
287 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
289 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
290 score = score + SCORE_DISTRO;
297 pplayer->base.ym = 0;
298 pplayer->jumping = NO;
299 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
302 /* Bump into things: * /
304 if (issolid(pplayer->base.x, pplayer->base.y) ||
305 (pplayer->size == BIG && !pplayer->duck &&
306 (issolid(pplayer->base.x, pplayer->base.y - 32))))
309 if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
310 (pplayer->size == SMALL || pplayer->duck ||
311 !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
313 if (pplayer->base.ym <= 0)
316 /* FIXME: this code is COMPLETLY broken!!! */
317 if (pplayer->size == BIG)
319 /* Break bricks and empty boxes: * /
323 if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
324 isfullbox(pplayer->base.x, pplayer->base.y - 32))
326 trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
327 trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
329 if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
331 bumpbrick(pplayer->base.x, pplayer->base.y - 32);
334 trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
335 tryemptybox(pplayer->base.x, pplayer->base.y - 32);
338 if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
339 isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
341 trygrabdistro(pplayer->base.x+ 31,
342 pplayer->base.y - 64,
344 trybumpbadguy(pplayer->base.x+ 31,
345 pplayer->base.y - 96);
347 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
349 bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
352 trybreakbrick(pplayer->base.x+ 31,
353 pplayer->base.y - 32);
354 tryemptybox(pplayer->base.x+ 31,
355 pplayer->base.y - 32);
360 if (isbrick(pplayer->base.x, pplayer->base.y) ||
361 isfullbox(pplayer->base.x, pplayer->base.y))
363 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
364 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
365 if (isfullbox(pplayer->base.x, pplayer->base.y))
366 bumpbrick(pplayer->base.x, pplayer->base.y);
367 trybreakbrick(pplayer->base.x, pplayer->base.y);
368 tryemptybox(pplayer->base.x, pplayer->base.y);
371 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
372 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
374 trygrabdistro(pplayer->base.x+ 31,
375 pplayer->base.y - 32,
377 trybumpbadguy(pplayer->base.x+ 31,
378 pplayer->base.y - 64);
379 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
380 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
381 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
382 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
388 /* It's a brick and we're small, make the brick
389 bounce, and grab any distros above it: * /
391 if (isbrick(pplayer->base.x, pplayer->base.y) ||
392 isfullbox(pplayer->base.x, pplayer->base.y))
394 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
395 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
396 bumpbrick(pplayer->base.x, pplayer->base.y);
397 tryemptybox(pplayer->base.x, pplayer->base.y);
400 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
401 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
403 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
404 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
405 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
406 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
410 /* Get a distro from a brick? * /
412 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
413 shape(pplayer->base.x, pplayer->base.y) == 'y')
415 add_bouncy_distro(((pplayer->base.x+ 1)
417 (int)(pplayer->base.y / 32) * 32);
419 if (counting_distros == NO)
421 counting_distros = YES;
422 distro_counter = 100;
425 if (distro_counter <= 0)
426 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
428 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
429 score = score + SCORE_DISTRO;
432 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
433 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
435 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
437 (int)(pplayer->base.y / 32) * 32);
439 if (counting_distros == NO)
441 counting_distros = YES;
442 distro_counter = 100;
445 if (distro_counter <= 0)
446 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
448 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
449 score = score + SCORE_DISTRO;
457 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
463 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
466 pplayer->base.ym = 0;
467 pplayer->jumping = NO;
468 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
475 player_grabdistros(pplayer);
478 /* Slow down horizontally: */
482 if (pplayer->input.right == UP && pplayer->input.left == UP)
484 if (isice(pplayer->base.x, pplayer->base.y + 32) ||
485 !issolid(pplayer->base.x, pplayer->base.y + 32))
487 /* Slowly on ice or in air: */
489 if (pplayer->base.xm > 0)
491 else if (pplayer->base.xm < 0)
496 /* Quickly, otherwise: */
498 pplayer->base.xm = pplayer->base.xm / 2;
503 /* Drop vertically: */
505 if (!issolid(pplayer->base.x, pplayer->base.y + 32))
507 pplayer->base.ym = pplayer->base.ym + GRAVITY;
509 if (pplayer->base.ym > MAX_YM)
510 pplayer->base.ym = MAX_YM;
516 timer_check(&pplayer->safe_timer);
519 /* ---- DONE HANDLING TUX! --- */
521 /* Handle invincibility timer: */
524 if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
527 no, we are no more invincible
528 or we were not in invincible mode
529 but are we in hurry ?
533 if (timer_get_left(&time_left) < TIME_WARNING)
535 /* yes, we are in hurry
536 stop the herring_song, prepare to play the correct
539 current_music = HURRYUP_MUSIC;
543 current_music = LEVEL_MUSIC;
546 /* stop the old music if it's being played */
551 /* Handle skidding: */
553 timer_check(&pplayer->skidding_timer);
557 if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
564 void player_handle_horizontal_input(player_type *pplayer, int dir)
566 if (pplayer->jumping == NO)
568 if ((dir ? (pplayer->base.xm < -SKID_XM) : (pplayer->base.xm > SKID_XM)) && !timer_started(&pplayer->skidding_timer) &&
569 pplayer->dir == !dir)
571 timer_start(&pplayer->skidding_timer, SKID_TIME);
573 play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
579 if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + 32) &&
580 !timer_started(&pplayer->skidding_timer))
582 pplayer->base.xm = 0;
587 if (pplayer->dir == dir)
589 /* Facing the direction we're jumping? Go full-speed: */
591 if (pplayer->input.fire == UP)
593 pplayer->base.xm = pplayer->base.xm + ( dir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
597 if (pplayer->base.xm > MAX_WALK_XM)
598 pplayer->base.xm = MAX_WALK_XM;
602 if (pplayer->base.xm < -MAX_WALK_XM)
603 pplayer->base.xm = -MAX_WALK_XM;
606 else if ( pplayer->input.fire == DOWN)
608 pplayer->base.xm = pplayer->base.xm + ( dir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
612 if (pplayer->base.xm > MAX_RUN_XM)
613 pplayer->base.xm = MAX_RUN_XM;
617 if (pplayer->base.xm < -MAX_RUN_XM)
618 pplayer->base.xm = -MAX_RUN_XM;
623 /* Not facing the direction we're jumping?
626 pplayer->base.xm = pplayer->base.xm + ( dir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
630 if (pplayer->base.xm > MAX_WALK_XM / 2)
631 pplayer->base.xm = MAX_WALK_XM / 2;
635 if (pplayer->base.xm < -MAX_WALK_XM / 2)
636 pplayer->base.xm = -MAX_WALK_XM / 2;
644 void player_handle_vertical_input(player_type *pplayer)
646 if(!timer_started(&pplayer->jump_timer))
648 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
653 if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
654 pplayer->base.ym != 0)
656 /* If they're not on the ground, or are currently moving
657 vertically, don't jump! */
659 pplayer->jumping = NO;
660 timer_stop(&pplayer->jump_timer);
664 /* Make sure we're not standing back up into a solid! */
666 if (pplayer->size == SMALL || pplayer->duck == NO ||
667 !issolid(pplayer->base.x, pplayer->base.y))
669 pplayer->jumping = YES;
671 if (pplayer->size == SMALL)
672 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
674 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
679 /* Keep jumping for a while: */
681 if (timer_check(&pplayer->jump_timer))
683 pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
684 if (pplayer->base.ym < -YM_FOR_JUMP)
685 pplayer->base.ym = -YM_FOR_JUMP;
689 void player_input(player_type *pplayer)
691 /* Handle key and joystick state: */
694 if (pplayer->input.right == DOWN && pplayer->input.left == UP)
696 player_handle_horizontal_input(pplayer,RIGHT);
698 else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
700 player_handle_horizontal_input(pplayer,LEFT);
705 if ( pplayer->input.up == DOWN)
707 player_handle_vertical_input(pplayer);
710 timer_stop(&pplayer->jump_timer);
714 if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
716 add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
722 if (pplayer->input.down == DOWN)
724 if (pplayer->size == BIG)
729 if (pplayer->size == BIG && pplayer->duck == YES)
731 /* Make sure we're not standing back up into a solid! */
733 if (!issolid(pplayer->base.x, pplayer->base.y - 32))
742 if (pplayer->input.right == UP && pplayer->input.left == UP)
744 pplayer->frame_main = 1;
749 if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
751 pplayer->frame_main = (pplayer->frame_main + 1) % 4;
753 pplayer->frame = pplayer->frame_main;
755 if (pplayer->frame == 3)
761 void player_grabdistros(player_type *pplayer)
766 trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
767 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
769 if (pplayer->size == BIG && !pplayer->duck)
771 trygrabdistro(pplayer->base.x, pplayer->base.y - 32, NO_BOUNCE);
772 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32, NO_BOUNCE);
777 /* Enough distros for a One-up? */
779 if (distros >= DISTROS_LIFEUP)
781 distros = distros - DISTROS_LIFEUP;
782 if(pplayer->lives < MAX_LIVES)
784 /*We want to hear the sound even, if MAX_LIVES is reached*/
785 play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
789 void player_draw(player_type* pplayer)
791 if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
793 if (pplayer->size == SMALL)
795 if (timer_started(&pplayer->invincible_timer))
799 if (pplayer->dir == RIGHT)
801 texture_draw(&cape_right[frame % 2],
802 pplayer->base.x- scroll_x, pplayer->base.y,
807 texture_draw(&cape_left[frame % 2],
808 pplayer->base.x- scroll_x, pplayer->base.y,
814 if (!pplayer->got_coffee)
816 if (pplayer->dir == RIGHT)
818 texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
822 texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
827 /* Tux got coffee! */
829 if (pplayer->dir == RIGHT)
831 texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
835 texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
841 if (timer_started(&pplayer->invincible_timer))
845 if (pplayer->dir == RIGHT)
847 texture_draw(&bigcape_right[frame % 2],
848 pplayer->base.x- scroll_x, pplayer->base.y,
853 texture_draw(&bigcape_left[frame % 2],
854 pplayer->base.x-scroll_x, pplayer->base.y,
859 if (!pplayer->got_coffee)
863 if (!timer_started(&pplayer->skidding_timer))
865 if (!pplayer->jumping || pplayer->base.ym > 0)
867 if (pplayer->dir == RIGHT)
869 texture_draw(&bigtux_right[pplayer->frame],
870 pplayer->base.x- scroll_x, pplayer->base.y,
875 texture_draw(&bigtux_left[pplayer->frame],
876 pplayer->base.x- scroll_x, pplayer->base.y,
882 if (pplayer->dir == RIGHT)
884 texture_draw(&bigtux_right_jump,
885 pplayer->base.x- scroll_x, pplayer->base.y,
890 texture_draw(&bigtux_left_jump,
891 pplayer->base.x- scroll_x, pplayer->base.y,
898 if (pplayer->dir == RIGHT)
900 texture_draw(&skidtux_right,
901 pplayer->base.x- scroll_x, pplayer->base.y,
906 texture_draw(&skidtux_left,
907 pplayer->base.x- scroll_x, pplayer->base.y,
914 if (pplayer->dir == RIGHT)
916 texture_draw(&ducktux_right, pplayer->base.x- scroll_x, pplayer->base.y,
921 texture_draw(&ducktux_left, pplayer->base.x- scroll_x, pplayer->base.y,
928 /* Tux has coffee! */
932 if (!timer_started(&pplayer->skidding_timer))
934 if (!pplayer->jumping || pplayer->base.ym > 0)
936 if (pplayer->dir == RIGHT)
938 texture_draw(&bigfiretux_right[pplayer->frame],
939 pplayer->base.x- scroll_x, pplayer->base.y,
944 texture_draw(&bigfiretux_left[pplayer->frame],
945 pplayer->base.x- scroll_x, pplayer->base.y,
951 if (pplayer->dir == RIGHT)
953 texture_draw(&bigfiretux_right_jump,
954 pplayer->base.x- scroll_x, pplayer->base.y,
959 texture_draw(&bigfiretux_left_jump,
960 pplayer->base.x- scroll_x, pplayer->base.y,
967 if (pplayer->dir == RIGHT)
969 texture_draw(&skidfiretux_right,
970 pplayer->base.x- scroll_x, pplayer->base.y,
975 texture_draw(&skidfiretux_left,
976 pplayer->base.x- scroll_x, pplayer->base.y,
983 if (pplayer->dir == RIGHT)
985 texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x, pplayer->base.y,
990 texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x, pplayer->base.y,
999 void player_collision(player_type* pplayer, void* p_c_object, int c_object)
1001 bad_guy_type* pbad_c = NULL;
1006 pbad_c = (bad_guy_type*) p_c_object;
1007 /* Hurt the player if he just touched it: */
1009 if (!pbad_c->dying && !pplayer->dying &&
1010 !timer_started(&pplayer->safe_timer) &&
1011 pbad_c->mode != HELD)
1013 if (pbad_c->mode == FLAT && pplayer->input.fire != DOWN)
1017 pbad_c->mode = KICK;
1018 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1020 if (pplayer->base.x<= pbad_c->base.x)
1022 pbad_c->dir = RIGHT;
1023 pbad_c->base.x = pbad_c->base.x + 16;
1028 pbad_c->base.x = pbad_c->base.x - 16;
1031 timer_start(&pbad_c->timer,5000);
1033 else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
1035 pbad_c->mode = HELD;
1038 else if (pbad_c->mode == KICK)
1040 if (pplayer->base.y < pbad_c->base.y - 16 &&
1041 timer_started(&pbad_c->timer))
1043 /* Step on (stop being kicked) */
1045 pbad_c->mode = FLAT;
1046 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1047 timer_start(&pbad_c->timer, 10000);
1051 /* Hurt if you get hit by kicked laptop: */
1053 if (timer_started(&pbad_c->timer))
1055 if (!timer_started(&pplayer->invincible_timer))
1057 player_kill(pplayer,SHRINK);
1061 pbad_c->dying = FALLING;
1062 pbad_c->base.ym = -8;
1063 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1070 if (!timer_started(&pplayer->invincible_timer ))
1072 player_kill(pplayer,SHRINK);
1076 pbad_c->dying = FALLING;
1077 pbad_c->base.ym = -8;
1078 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1092 void player_kill(player_type* pplayer, int mode)
1094 pplayer->base.ym = -5;
1096 play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
1098 if (pplayer->dir == RIGHT)
1099 pplayer->base.xm = -8;
1100 else if (pplayer->dir == LEFT)
1101 pplayer->base.xm = 8;
1103 if (mode == SHRINK && pplayer->size == BIG)
1105 if (pplayer->got_coffee)
1106 pplayer->got_coffee = NO;
1108 pplayer->size = SMALL;
1109 pplayer->base.height = 32;
1111 timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
1119 void player_dying(player_type *pplayer)
1121 pplayer->base.ym = pplayer->base.ym + GRAVITY;
1126 player_remove_powerups(pplayer);
1127 pplayer->dying = NO;
1129 player_level_begin(pplayer);
1133 /* Remove Tux's power ups */
1134 void player_remove_powerups(player_type* pplayer)
1136 pplayer->got_coffee = NO;
1137 pplayer->size = SMALL;
1138 pplayer->base.height = 32;
1141 void player_keep_in_bounds(player_type* pplayer)
1143 /* Keep tux in bounds: */
1144 if (pplayer->base.x< 0)
1146 else if(pplayer->base.x< scroll_x)
1147 pplayer->base.x= scroll_x;
1148 else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
1150 scroll_x = pplayer->base.x- 160;
1151 /*pplayer->base.x+= 160;*/
1157 else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
1159 /* Scroll the screen in past center: */
1161 scroll_x = pplayer->base.x- screen->w / 2;
1162 /*pplayer->base.x= 320 + scroll_x;*/
1164 if (scroll_x > ((current_level.width * 32) - screen->w))
1165 scroll_x = ((current_level.width * 32) - screen->w);
1167 else if (pplayer->base.x> 608 + scroll_x)
1169 /* ... unless there's no more to scroll! */
1171 /*pplayer->base.x= 608 + scroll_x;*/
1174 /* Keep in-bounds, vertically: */
1176 if (pplayer->base.y < 0)
1177 pplayer->base.y = 0;
1178 else if (pplayer->base.y > screen->h)
1180 player_kill(&tux,KILL);