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;
58 pplayer->input.down = UP;
59 pplayer->input.fire = UP;
60 pplayer->input.left = UP;
61 pplayer->input.old_fire = UP;
62 pplayer->input.right = UP;
63 pplayer->input.up = UP;
65 pplayer->keymap.jump = SDLK_UP;
66 pplayer->keymap.duck = SDLK_DOWN;
67 pplayer->keymap.left = SDLK_LEFT;
68 pplayer->keymap.right = SDLK_RIGHT;
69 pplayer->keymap.fire = SDLK_LCTRL;
71 timer_init(&pplayer->invincible_timer,YES);
72 timer_init(&pplayer->skidding_timer,YES);
73 timer_init(&pplayer->safe_timer,YES);
74 physic_init(&pplayer->hphysic);
75 physic_init(&pplayer->vphysic);
78 int player_key_event(player_type* pplayer, SDLKey key, int state)
80 if(key == pplayer->keymap.right)
82 pplayer->input.right = state;
85 else if( key == pplayer->keymap.left)
87 pplayer->input.left = state;
90 else if(key == pplayer->keymap.jump)
92 pplayer->input.up = state;
95 else if(key == pplayer->keymap.duck)
97 pplayer->input.down = state;
100 else if(key == pplayer->keymap.fire)
102 pplayer->input.fire = state;
109 void player_level_begin(player_type* pplayer)
112 pplayer->base.y = 240;
113 pplayer->base.xm = 0;
114 pplayer->base.ym = 0;
116 pplayer->input.down = UP;
117 pplayer->input.fire = UP;
118 pplayer->input.left = UP;
119 pplayer->input.old_fire = UP;
120 pplayer->input.right = UP;
121 pplayer->input.up = UP;
123 timer_init(&pplayer->invincible_timer,YES);
124 timer_init(&pplayer->skidding_timer,YES);
125 timer_init(&pplayer->safe_timer,YES);
128 void player_action(player_type* pplayer)
130 /* --- HANDLE TUX! --- */
132 player_input(pplayer);
136 pplayer->base.x += pplayer->base.xm * frame_ratio;
137 pplayer->base.y += pplayer->base.ym * frame_ratio;
139 player_keep_in_bounds(pplayer);
146 /*if(physic_is_set(&pplayer->vphysic))
148 pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
152 if( /*!issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height )*/ !player_on_ground(pplayer))
154 if(!physic_is_set(&pplayer->vphysic))
156 physic_set_state(&pplayer->vphysic,PH_VT);
157 physic_set_start_vy(&pplayer->vphysic,0.);
159 pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
165 if (pplayer->base.ym > 0)
167 pplayer->base.y = (int)(((int)(pplayer->base.y +1) / 32) * 32);
168 pplayer->base.ym = 0;
170 physic_init(&pplayer->vphysic);
173 while(issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16, pplayer->base.y))
177 while(issolid( pplayer->base.x + 16, pplayer->base.y + 1) && !issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height))
181 while(issolid( pplayer->base.x - 1, pplayer->base.y + 1) || issolid( pplayer->base.x - 1, pplayer->base.y+pplayer->base.height))
185 while(issolid( pplayer->base.x + 32, pplayer->base.y + 1) || issolid( pplayer->base.x + 32, pplayer->base.y+pplayer->base.height))
190 if(pplayer->base.ym <= 0)
193 if (isbrick(pplayer->base.x, pplayer->base.y) ||
194 isfullbox(pplayer->base.x, pplayer->base.y))
196 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
197 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
199 if(pplayer->size == BIG)
200 trybreakbrick(pplayer->base.x, pplayer->base.y);
202 bumpbrick(pplayer->base.x, pplayer->base.y);
203 tryemptybox(pplayer->base.x, pplayer->base.y);
206 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
207 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
209 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
210 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
212 if(pplayer->size == BIG)
213 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
215 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
216 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
220 if(pplayer->size == SMALL)
222 /* Get a distro from a brick? */
224 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
225 shape(pplayer->base.x, pplayer->base.y) == 'y')
227 add_bouncy_distro((((int)pplayer->base.x)
229 ((int)pplayer->base.y / 32) * 32);
230 if (counting_distros == NO)
232 counting_distros = YES;
233 distro_counter = 100;
236 if (distro_counter <= 0)
237 level_change(¤t_level,pplayer->base.x,pplayer->base.y - 1, 'a');
239 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
240 score = score + SCORE_DISTRO;
243 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
244 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
246 add_bouncy_distro((((int)pplayer->base.x + 31)
248 ((int)pplayer->base.y / 32) * 32);
249 if (counting_distros == NO)
251 counting_distros = YES;
252 distro_counter = 100;
255 if (distro_counter <= 0)
256 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
258 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
259 score = score + SCORE_DISTRO;
265 player_grabdistros(pplayer);
267 /* FIXME: this code is COMPLETLY broken!!! */
268 /* if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
269 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
271 while (issolid(pplayer->base.x, pplayer->base.y + 31))
273 if (pplayer->base.xm < 0)
275 else if (pplayer->base.xm > 0)
279 pplayer->base.xm = 0;
282 /*if (issolid(pplayer->base.x, pplayer->base.y) &&
283 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
285 while (issolid(pplayer->base.x, (pplayer->base.y)))
287 if (pplayer->base.xm < 0)
289 else if (pplayer->base.xm > 0)
293 pplayer->base.xm = 0;
296 /*if (issolid(pplayer->base.x, pplayer->base.y + 31))
298 /* Set down properly: * /
301 while (issolid(pplayer->base.x, pplayer->base.y + 31))
306 DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
307 /*the circumstances are:
308 issolid() is true and base.ym == 0
309 use of floating point varibles for base stuff* /
312 if (pplayer->base.ym < 0)
314 else if (pplayer->base.ym > 0)
319 /* Reset score multiplier (for multi-hits): */
321 if (pplayer->base.ym > 0)
322 score_multiplier = 1;
327 pplayer->base.ym = 0;
328 pplayer->jumping = NO;
329 pplayer->input.up = UP;
331 /* FIXME: this code is COMPLETLY broken!!! */
332 /*if (issolid(pplayer->base.x, pplayer->base.y) ||
333 (pplayer->size == BIG && !pplayer->duck &&
334 (issolid(pplayer->base.x, pplayer->base.y - 32))))
336 /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
337 (pplayer->size == SMALL || pplayer->duck ||
338 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))* /
340 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))))
341 ||((!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)))))
342 /*(pplayer->size == SMALL || pplayer->duck ||
343 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /
345 pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio;
346 pplayer->base.ym = 0;
349 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))
350 /*(pplayer->size == SMALL || pplayer->duck ||
351 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /) ||
352 (!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))))
354 pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio;
355 pplayer->base.xm = 0;
358 if (pplayer->base.ym <= 0)
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 bumpbrick(pplayer->base.x, pplayer->base.y);
366 tryemptybox(pplayer->base.x, pplayer->base.y);
369 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
370 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
372 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
373 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
374 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
375 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
377 /* Get a distro from a brick? * /
379 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
380 shape(pplayer->base.x, pplayer->base.y) == 'y')
382 add_bouncy_distro(((pplayer->base.x+ 1)
384 (int)(pplayer->base.y / 32) * 32);
386 if (counting_distros == NO)
388 counting_distros = YES;
389 distro_counter = 100;
392 if (distro_counter <= 0)
393 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
395 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
396 score = score + SCORE_DISTRO;
399 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
400 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
402 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
404 (int)(pplayer->base.y / 32) * 32);
406 if (counting_distros == NO)
408 counting_distros = YES;
409 distro_counter = 100;
412 if (distro_counter <= 0)
413 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
415 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
416 score = score + SCORE_DISTRO;
423 pplayer->base.ym = 0;
424 pplayer->jumping = NO;
425 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
428 /* Bump into things: * /
430 if (issolid(pplayer->base.x, pplayer->base.y) ||
431 (pplayer->size == BIG && !pplayer->duck &&
432 (issolid(pplayer->base.x, pplayer->base.y - 32))))
435 if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
436 (pplayer->size == SMALL || pplayer->duck ||
437 !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
439 if (pplayer->base.ym <= 0)
442 /* FIXME: this code is COMPLETLY broken!!! */
443 if (pplayer->size == BIG)
445 /* Break bricks and empty boxes: * /
449 if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
450 isfullbox(pplayer->base.x, pplayer->base.y - 32))
452 trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
453 trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
455 if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
457 bumpbrick(pplayer->base.x, pplayer->base.y - 32);
460 trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
461 tryemptybox(pplayer->base.x, pplayer->base.y - 32);
464 if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
465 isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
467 trygrabdistro(pplayer->base.x+ 31,
468 pplayer->base.y - 64,
470 trybumpbadguy(pplayer->base.x+ 31,
471 pplayer->base.y - 96);
473 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
475 bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
478 trybreakbrick(pplayer->base.x+ 31,
479 pplayer->base.y - 32);
480 tryemptybox(pplayer->base.x+ 31,
481 pplayer->base.y - 32);
486 if (isbrick(pplayer->base.x, pplayer->base.y) ||
487 isfullbox(pplayer->base.x, pplayer->base.y))
489 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
490 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
491 if (isfullbox(pplayer->base.x, pplayer->base.y))
492 bumpbrick(pplayer->base.x, pplayer->base.y);
493 trybreakbrick(pplayer->base.x, pplayer->base.y);
494 tryemptybox(pplayer->base.x, pplayer->base.y);
497 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
498 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
500 trygrabdistro(pplayer->base.x+ 31,
501 pplayer->base.y - 32,
503 trybumpbadguy(pplayer->base.x+ 31,
504 pplayer->base.y - 64);
505 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
506 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
507 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
508 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
514 /* It's a brick and we're small, make the brick
515 bounce, and grab any distros above it: * /
517 if (isbrick(pplayer->base.x, pplayer->base.y) ||
518 isfullbox(pplayer->base.x, pplayer->base.y))
520 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
521 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
522 bumpbrick(pplayer->base.x, pplayer->base.y);
523 tryemptybox(pplayer->base.x, pplayer->base.y);
526 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
527 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
529 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
530 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
531 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
532 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
536 /* Get a distro from a brick? * /
538 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
539 shape(pplayer->base.x, pplayer->base.y) == 'y')
541 add_bouncy_distro(((pplayer->base.x+ 1)
543 (int)(pplayer->base.y / 32) * 32);
545 if (counting_distros == NO)
547 counting_distros = YES;
548 distro_counter = 100;
551 if (distro_counter <= 0)
552 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
554 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
555 score = score + SCORE_DISTRO;
558 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
559 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
561 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
563 (int)(pplayer->base.y / 32) * 32);
565 if (counting_distros == NO)
567 counting_distros = YES;
568 distro_counter = 100;
571 if (distro_counter <= 0)
572 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
574 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
575 score = score + SCORE_DISTRO;
583 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
589 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
592 pplayer->base.ym = 0;
593 pplayer->jumping = NO;
594 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
601 player_grabdistros(pplayer);
604 /* Slow down horizontally: * /
608 if (pplayer->input.right == UP && pplayer->input.left == UP)
610 if (isice(pplayer->base.x, pplayer->base.y + 32) ||
611 !issolid(pplayer->base.x, pplayer->base.y + 32))
613 /* Slowly on ice or in air: * /
615 if (pplayer->base.xm > 0)
617 else if (pplayer->base.xm < 0)
622 /* Quickly, otherwise: * /
624 pplayer->base.xm = pplayer->base.xm / 2;
629 /* Drop vertically: * /
631 if (!issolid(pplayer->base.x, pplayer->base.y + 32))
633 pplayer->base.ym = pplayer->base.ym + GRAVITY;
635 if (pplayer->base.ym > MAX_YM)
636 pplayer->base.ym = MAX_YM;
642 timer_check(&pplayer->safe_timer);
645 /* ---- DONE HANDLING TUX! --- */
647 /* Handle invincibility timer: */
650 if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
653 no, we are no more invincible
654 or we were not in invincible mode
655 but are we in hurry ?
659 if (timer_get_left(&time_left) < TIME_WARNING)
661 /* yes, we are in hurry
662 stop the herring_song, prepare to play the correct
665 current_music = HURRYUP_MUSIC;
669 current_music = LEVEL_MUSIC;
672 /* stop the old music if it's being played */
677 /* Handle skidding: */
679 timer_check(&pplayer->skidding_timer);
683 if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
690 int player_on_ground(player_type *pplayer)
692 if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height + 1) ||
693 issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height + 1) ||
694 issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height + 1) )
704 void player_handle_horizontal_input(player_type *pplayer, int dir)
706 if (pplayer->jumping == NO)
708 if ((dir ? (pplayer->base.xm < -SKID_XM) : (pplayer->base.xm > SKID_XM)) && !timer_started(&pplayer->skidding_timer) &&
709 pplayer->dir == !dir)
711 timer_start(&pplayer->skidding_timer, SKID_TIME);
713 play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
719 if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + 32) &&
720 !timer_started(&pplayer->skidding_timer))
722 pplayer->base.xm = 0;
727 if (pplayer->dir == dir)
729 /* Facing the direction we're jumping? Go full-speed: */
731 if (pplayer->input.fire == UP)
733 pplayer->base.xm = pplayer->base.xm + ( dir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
737 if (pplayer->base.xm > MAX_WALK_XM)
738 pplayer->base.xm = MAX_WALK_XM;
742 if (pplayer->base.xm < -MAX_WALK_XM)
743 pplayer->base.xm = -MAX_WALK_XM;
746 else if ( pplayer->input.fire == DOWN)
748 pplayer->base.xm = pplayer->base.xm + ( dir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
752 if (pplayer->base.xm > MAX_RUN_XM)
753 pplayer->base.xm = MAX_RUN_XM;
757 if (pplayer->base.xm < -MAX_RUN_XM)
758 pplayer->base.xm = -MAX_RUN_XM;
763 /* Not facing the direction we're jumping?
766 pplayer->base.xm = pplayer->base.xm + ( dir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
770 if (pplayer->base.xm > MAX_WALK_XM / 2)
771 pplayer->base.xm = MAX_WALK_XM / 2;
775 if (pplayer->base.xm < -MAX_WALK_XM / 2)
776 pplayer->base.xm = -MAX_WALK_XM / 2;
784 void player_handle_vertical_input(player_type *pplayer)
786 if(pplayer->input.up == DOWN)
788 if (player_on_ground(pplayer))
790 if(!physic_is_set(&pplayer->vphysic))
792 physic_set_state(&pplayer->vphysic,PH_VT);
793 physic_set_start_vy(&pplayer->vphysic,5.5);
795 pplayer->jumping = YES;
796 if (pplayer->size == SMALL)
797 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
799 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
803 else if(pplayer->input.up == UP && pplayer->jumping == YES)
806 DEBUG_MSG("Stop Jump");
807 pplayer->jumping = NO;
809 if (pplayer->base.ym > 0)
811 pplayer->base.y = (int)(pplayer->base.y / 32) * 32;
812 pplayer->base.ym = 0;
814 physic_init(&pplayer->vphysic);
816 else if(pplayer->input.up == UP)
818 if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
820 physic_init(&pplayer->vphysic);
821 pplayer->jumping == NO;
825 pplayer->jumping = NO;
826 printf("%f",physic_get_velocity(&pplayer->vphysic));
827 if(physic_is_set(&pplayer->vphysic))
829 if(physic_get_velocity(&pplayer->vphysic) < 0.)
831 physic_set_state(&pplayer->vphysic,PH_VT);
832 physic_set_start_vy(&pplayer->vphysic,0);
837 if(!physic_is_set(&pplayer->vphysic))
839 physic_set_state(&pplayer->vphysic,PH_VT);
847 if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
848 pplayer->base.ym != 0)
850 /* If they're not on the ground, or are currently moving
851 vertically, don't jump! * /
853 pplayer->jumping = NO;
854 timer_stop(&pplayer->jump_timer);
858 /* Make sure we're not standing back up into a solid! * /
860 if (pplayer->size == SMALL || pplayer->duck == NO ||
861 !issolid(pplayer->base.x, pplayer->base.y))
863 pplayer->jumping = YES;
865 if (pplayer->size == SMALL)
866 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
868 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
872 /* Keep jumping for a while: * /
874 if (timer_check(&pplayer->jump_timer))
876 pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
877 if (pplayer->base.ym < -YM_FOR_JUMP)
878 pplayer->base.ym = pplayer->base.ym/*-YM_FOR_JUMP* /;
882 void player_input(player_type *pplayer)
884 /* Handle key and joystick state: */
887 if (pplayer->input.right == DOWN && pplayer->input.left == UP)
889 player_handle_horizontal_input(pplayer,RIGHT);
891 else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
893 player_handle_horizontal_input(pplayer,LEFT);
897 if(pplayer->base.xm > 0)
898 pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio);
899 else if(pplayer->base.xm < 0)
900 pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio);
905 if ( pplayer->input.up == DOWN || (pplayer->input.up == UP && pplayer->jumping == YES))
907 player_handle_vertical_input(pplayer);
912 if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
914 add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
920 if (pplayer->input.down == DOWN)
922 if (pplayer->size == BIG)
927 if (pplayer->size == BIG && pplayer->duck == YES)
929 /* Make sure we're not standing back up into a solid! */
931 if (!issolid(pplayer->base.x + 16, pplayer->base.y - 16))
940 if (pplayer->input.right == UP && pplayer->input.left == UP)
942 pplayer->frame_main = 1;
947 if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
949 pplayer->frame_main = (pplayer->frame_main + 1) % 4;
951 pplayer->frame = pplayer->frame_main;
953 if (pplayer->frame == 3)
959 void player_grabdistros(player_type *pplayer)
964 trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
965 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
967 trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
968 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
970 if(pplayer->size == BIG)
972 trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
973 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
979 /* Enough distros for a One-up? */
981 if (distros >= DISTROS_LIFEUP)
983 distros = distros - DISTROS_LIFEUP;
984 if(pplayer->lives < MAX_LIVES)
986 /*We want to hear the sound even, if MAX_LIVES is reached*/
987 play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
991 void player_draw(player_type* pplayer)
993 if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
995 if (pplayer->size == SMALL)
997 if (timer_started(&pplayer->invincible_timer))
1001 if (pplayer->dir == RIGHT)
1003 texture_draw(&cape_right[frame % 2],
1004 pplayer->base.x- scroll_x, pplayer->base.y,
1009 texture_draw(&cape_left[frame % 2],
1010 pplayer->base.x- scroll_x, pplayer->base.y,
1016 if (!pplayer->got_coffee)
1018 if (pplayer->dir == RIGHT)
1020 texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1024 texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1029 /* Tux got coffee! */
1031 if (pplayer->dir == RIGHT)
1033 texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1037 texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1043 if (timer_started(&pplayer->invincible_timer))
1047 if (pplayer->dir == RIGHT)
1049 texture_draw(&bigcape_right[frame % 2],
1050 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1055 texture_draw(&bigcape_left[frame % 2],
1056 pplayer->base.x-scroll_x - 8, pplayer->base.y,
1061 if (!pplayer->got_coffee)
1065 if (!timer_started(&pplayer->skidding_timer))
1067 if (!pplayer->jumping || pplayer->base.ym > 0)
1069 if (pplayer->dir == RIGHT)
1071 texture_draw(&bigtux_right[pplayer->frame],
1072 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1077 texture_draw(&bigtux_left[pplayer->frame],
1078 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1084 if (pplayer->dir == RIGHT)
1086 texture_draw(&bigtux_right_jump,
1087 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1092 texture_draw(&bigtux_left_jump,
1093 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1100 if (pplayer->dir == RIGHT)
1102 texture_draw(&skidtux_right,
1103 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1108 texture_draw(&skidtux_left,
1109 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1116 if (pplayer->dir == RIGHT)
1118 texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1123 texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1130 /* Tux has coffee! */
1134 if (!timer_started(&pplayer->skidding_timer))
1136 if (!pplayer->jumping || pplayer->base.ym > 0)
1138 if (pplayer->dir == RIGHT)
1140 texture_draw(&bigfiretux_right[pplayer->frame],
1141 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1146 texture_draw(&bigfiretux_left[pplayer->frame],
1147 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1153 if (pplayer->dir == RIGHT)
1155 texture_draw(&bigfiretux_right_jump,
1156 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1161 texture_draw(&bigfiretux_left_jump,
1162 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1169 if (pplayer->dir == RIGHT)
1171 texture_draw(&skidfiretux_right,
1172 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1177 texture_draw(&skidfiretux_left,
1178 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1185 if (pplayer->dir == RIGHT)
1187 texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1192 texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1201 void player_collision(player_type* pplayer, void* p_c_object, int c_object)
1203 bad_guy_type* pbad_c = NULL;
1208 pbad_c = (bad_guy_type*) p_c_object;
1209 /* Hurt the player if he just touched it: */
1211 if (!pbad_c->dying && !pplayer->dying &&
1212 !timer_started(&pplayer->safe_timer) &&
1213 pbad_c->mode != HELD)
1215 if (pbad_c->mode == FLAT && pplayer->input.fire != DOWN)
1219 pbad_c->mode = KICK;
1220 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1222 if (pplayer->base.x<= pbad_c->base.x)
1224 pbad_c->dir = RIGHT;
1225 pbad_c->base.x = pbad_c->base.x + 16;
1230 pbad_c->base.x = pbad_c->base.x - 16;
1233 timer_start(&pbad_c->timer,5000);
1235 else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
1237 pbad_c->mode = HELD;
1240 else if (pbad_c->mode == KICK)
1242 if (pplayer->base.y < pbad_c->base.y - 16 &&
1243 timer_started(&pbad_c->timer))
1245 /* Step on (stop being kicked) */
1247 pbad_c->mode = FLAT;
1248 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1249 timer_start(&pbad_c->timer, 10000);
1253 /* Hurt if you get hit by kicked laptop: */
1255 if (timer_started(&pbad_c->timer))
1257 if (!timer_started(&pplayer->invincible_timer))
1259 player_kill(pplayer,SHRINK);
1263 pbad_c->dying = FALLING;
1264 pbad_c->base.ym = -8;
1265 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1272 if (!timer_started(&pplayer->invincible_timer ))
1274 player_kill(pplayer,SHRINK);
1278 pbad_c->dying = FALLING;
1279 pbad_c->base.ym = -8;
1280 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1294 void player_kill(player_type* pplayer, int mode)
1296 pplayer->base.ym = -5;
1298 play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
1300 if (pplayer->dir == RIGHT)
1301 pplayer->base.xm = -8;
1302 else if (pplayer->dir == LEFT)
1303 pplayer->base.xm = 8;
1305 if (mode == SHRINK && pplayer->size == BIG)
1307 if (pplayer->got_coffee)
1308 pplayer->got_coffee = NO;
1310 pplayer->size = SMALL;
1311 pplayer->base.height = 32;
1313 timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
1321 void player_dying(player_type *pplayer)
1323 pplayer->base.ym = pplayer->base.ym + gravity;
1328 player_remove_powerups(pplayer);
1329 pplayer->dying = NO;
1331 player_level_begin(pplayer);
1335 /* Remove Tux's power ups */
1336 void player_remove_powerups(player_type* pplayer)
1338 pplayer->got_coffee = NO;
1339 pplayer->size = SMALL;
1340 pplayer->base.height = 32;
1343 void player_keep_in_bounds(player_type* pplayer)
1345 /* Keep tux in bounds: */
1346 if (pplayer->base.x< 0)
1348 else if(pplayer->base.x< scroll_x)
1349 pplayer->base.x= scroll_x;
1350 else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
1352 scroll_x = pplayer->base.x- 160;
1353 /*pplayer->base.x+= 160;*/
1359 else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
1361 /* Scroll the screen in past center: */
1363 scroll_x = pplayer->base.x- screen->w / 2;
1364 /*pplayer->base.x= 320 + scroll_x;*/
1366 if (scroll_x > ((current_level.width * 32) - screen->w))
1367 scroll_x = ((current_level.width * 32) - screen->w);
1369 else if (pplayer->base.x> 608 + scroll_x)
1371 /* ... unless there's no more to scroll! */
1373 /*pplayer->base.x= 608 + scroll_x;*/
1376 /* Keep in-bounds, vertically: */
1378 if (pplayer->base.y < 0)
1379 pplayer->base.y = 0;
1380 else if (pplayer->base.y > screen->h)
1382 player_kill(&tux,KILL);