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.);
158 DEBUG_MSG("Ich bin jetzt ordentlich am Punkten");
160 pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
166 if (pplayer->base.ym > 0)
168 pplayer->base.y = (int)(((int)(pplayer->base.y +1) / 32) * 32);
169 printf("%f",pplayer->base.y);
170 pplayer->base.ym = 0;
172 physic_init(&pplayer->vphysic);
175 while(issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16, pplayer->base.y))
179 while(issolid( pplayer->base.x + 16, pplayer->base.y + 1) && !issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height))
183 while(issolid( pplayer->base.x - 1, pplayer->base.y + 1) || issolid( pplayer->base.x - 1, pplayer->base.y+pplayer->base.height))
187 while(issolid( pplayer->base.x + 32, pplayer->base.y + 1) || issolid( pplayer->base.x + 32, pplayer->base.y+pplayer->base.height))
192 if(pplayer->base.ym <= 0)
195 if (isbrick(pplayer->base.x, pplayer->base.y) ||
196 isfullbox(pplayer->base.x, pplayer->base.y))
198 DEBUG_MSG("My sear");
199 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
200 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
202 if(pplayer->size == BIG)
203 trybreakbrick(pplayer->base.x, pplayer->base.y);
205 bumpbrick(pplayer->base.x, pplayer->base.y);
206 tryemptybox(pplayer->base.x, pplayer->base.y);
209 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
210 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
212 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
213 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
215 if(pplayer->size == BIG)
216 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
218 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
219 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
223 if(pplayer->size == SMALL)
225 /* Get a distro from a brick? */
227 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
228 shape(pplayer->base.x, pplayer->base.y) == 'y')
230 add_bouncy_distro((((int)pplayer->base.x)
232 ((int)pplayer->base.y / 32) * 32);
233 DEBUG_MSG("should work");
234 if (counting_distros == NO)
236 counting_distros = YES;
237 distro_counter = 100;
240 if (distro_counter <= 0)
241 level_change(¤t_level,pplayer->base.x,pplayer->base.y - 1, 'a');
243 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
244 score = score + SCORE_DISTRO;
247 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
248 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
250 add_bouncy_distro((((int)pplayer->base.x + 31)
252 ((int)pplayer->base.y / 32) * 32);
254 if (counting_distros == NO)
256 counting_distros = YES;
257 distro_counter = 100;
260 if (distro_counter <= 0)
261 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
263 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
264 score = score + SCORE_DISTRO;
270 player_grabdistros(pplayer);
272 /* FIXME: this code is COMPLETLY broken!!! */
273 /* if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
274 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
276 while (issolid(pplayer->base.x, pplayer->base.y + 31))
278 if (pplayer->base.xm < 0)
280 else if (pplayer->base.xm > 0)
284 pplayer->base.xm = 0;
287 /*if (issolid(pplayer->base.x, pplayer->base.y) &&
288 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
290 while (issolid(pplayer->base.x, (pplayer->base.y)))
292 if (pplayer->base.xm < 0)
294 else if (pplayer->base.xm > 0)
298 pplayer->base.xm = 0;
301 /*if (issolid(pplayer->base.x, pplayer->base.y + 31))
303 /* Set down properly: * /
306 while (issolid(pplayer->base.x, pplayer->base.y + 31))
311 DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
312 /*the circumstances are:
313 issolid() is true and base.ym == 0
314 use of floating point varibles for base stuff* /
317 if (pplayer->base.ym < 0)
319 else if (pplayer->base.ym > 0)
324 /* Reset score multiplier (for multi-hits): */
326 if (pplayer->base.ym > 0)
327 score_multiplier = 1;
332 pplayer->base.ym = 0;
333 pplayer->jumping = NO;
334 pplayer->input.up = UP;
336 /* FIXME: this code is COMPLETLY broken!!! */
337 /*if (issolid(pplayer->base.x, pplayer->base.y) ||
338 (pplayer->size == BIG && !pplayer->duck &&
339 (issolid(pplayer->base.x, pplayer->base.y - 32))))
341 /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
342 (pplayer->size == SMALL || pplayer->duck ||
343 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))* /
345 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))))
346 ||((!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)))))
347 /*(pplayer->size == SMALL || pplayer->duck ||
348 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /
350 pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio;
351 pplayer->base.ym = 0;
354 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))
355 /*(pplayer->size == SMALL || pplayer->duck ||
356 !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /) ||
357 (!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))))
359 pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio;
360 pplayer->base.xm = 0;
363 if (pplayer->base.ym <= 0)
365 if (isbrick(pplayer->base.x, pplayer->base.y) ||
366 isfullbox(pplayer->base.x, pplayer->base.y))
368 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
369 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
370 bumpbrick(pplayer->base.x, pplayer->base.y);
371 tryemptybox(pplayer->base.x, pplayer->base.y);
374 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
375 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
377 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
378 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
379 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
380 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
382 /* Get a distro from a brick? * /
384 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
385 shape(pplayer->base.x, pplayer->base.y) == 'y')
387 add_bouncy_distro(((pplayer->base.x+ 1)
389 (int)(pplayer->base.y / 32) * 32);
391 if (counting_distros == NO)
393 counting_distros = YES;
394 distro_counter = 100;
397 if (distro_counter <= 0)
398 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
400 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
401 score = score + SCORE_DISTRO;
404 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
405 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
407 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
409 (int)(pplayer->base.y / 32) * 32);
411 if (counting_distros == NO)
413 counting_distros = YES;
414 distro_counter = 100;
417 if (distro_counter <= 0)
418 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
420 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
421 score = score + SCORE_DISTRO;
428 pplayer->base.ym = 0;
429 pplayer->jumping = NO;
430 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
433 /* Bump into things: * /
435 if (issolid(pplayer->base.x, pplayer->base.y) ||
436 (pplayer->size == BIG && !pplayer->duck &&
437 (issolid(pplayer->base.x, pplayer->base.y - 32))))
440 if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
441 (pplayer->size == SMALL || pplayer->duck ||
442 !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
444 if (pplayer->base.ym <= 0)
447 /* FIXME: this code is COMPLETLY broken!!! */
448 if (pplayer->size == BIG)
450 /* Break bricks and empty boxes: * /
454 if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
455 isfullbox(pplayer->base.x, pplayer->base.y - 32))
457 trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
458 trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
460 if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
462 bumpbrick(pplayer->base.x, pplayer->base.y - 32);
465 trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
466 tryemptybox(pplayer->base.x, pplayer->base.y - 32);
469 if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
470 isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
472 trygrabdistro(pplayer->base.x+ 31,
473 pplayer->base.y - 64,
475 trybumpbadguy(pplayer->base.x+ 31,
476 pplayer->base.y - 96);
478 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
480 bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
483 trybreakbrick(pplayer->base.x+ 31,
484 pplayer->base.y - 32);
485 tryemptybox(pplayer->base.x+ 31,
486 pplayer->base.y - 32);
491 if (isbrick(pplayer->base.x, pplayer->base.y) ||
492 isfullbox(pplayer->base.x, pplayer->base.y))
494 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
495 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
496 if (isfullbox(pplayer->base.x, pplayer->base.y))
497 bumpbrick(pplayer->base.x, pplayer->base.y);
498 trybreakbrick(pplayer->base.x, pplayer->base.y);
499 tryemptybox(pplayer->base.x, pplayer->base.y);
502 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
503 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
505 trygrabdistro(pplayer->base.x+ 31,
506 pplayer->base.y - 32,
508 trybumpbadguy(pplayer->base.x+ 31,
509 pplayer->base.y - 64);
510 if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
511 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
512 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
513 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
519 /* It's a brick and we're small, make the brick
520 bounce, and grab any distros above it: * /
522 if (isbrick(pplayer->base.x, pplayer->base.y) ||
523 isfullbox(pplayer->base.x, pplayer->base.y))
525 trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
526 trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
527 bumpbrick(pplayer->base.x, pplayer->base.y);
528 tryemptybox(pplayer->base.x, pplayer->base.y);
531 if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
532 isfullbox(pplayer->base.x+ 31, pplayer->base.y))
534 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
535 trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
536 bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
537 tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
541 /* Get a distro from a brick? * /
543 if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
544 shape(pplayer->base.x, pplayer->base.y) == 'y')
546 add_bouncy_distro(((pplayer->base.x+ 1)
548 (int)(pplayer->base.y / 32) * 32);
550 if (counting_distros == NO)
552 counting_distros = YES;
553 distro_counter = 100;
556 if (distro_counter <= 0)
557 level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a');
559 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
560 score = score + SCORE_DISTRO;
563 else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
564 shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
566 add_bouncy_distro(((pplayer->base.x+ 1 + 31)
568 (int)(pplayer->base.y / 32) * 32);
570 if (counting_distros == NO)
572 counting_distros = YES;
573 distro_counter = 100;
576 if (distro_counter <= 0)
577 level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
579 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
580 score = score + SCORE_DISTRO;
588 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
594 pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
597 pplayer->base.ym = 0;
598 pplayer->jumping = NO;
599 timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
606 player_grabdistros(pplayer);
609 /* Slow down horizontally: * /
613 if (pplayer->input.right == UP && pplayer->input.left == UP)
615 if (isice(pplayer->base.x, pplayer->base.y + 32) ||
616 !issolid(pplayer->base.x, pplayer->base.y + 32))
618 /* Slowly on ice or in air: * /
620 if (pplayer->base.xm > 0)
622 else if (pplayer->base.xm < 0)
627 /* Quickly, otherwise: * /
629 pplayer->base.xm = pplayer->base.xm / 2;
634 /* Drop vertically: * /
636 if (!issolid(pplayer->base.x, pplayer->base.y + 32))
638 pplayer->base.ym = pplayer->base.ym + GRAVITY;
640 if (pplayer->base.ym > MAX_YM)
641 pplayer->base.ym = MAX_YM;
647 timer_check(&pplayer->safe_timer);
650 /* ---- DONE HANDLING TUX! --- */
652 /* Handle invincibility timer: */
655 if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
658 no, we are no more invincible
659 or we were not in invincible mode
660 but are we in hurry ?
664 if (timer_get_left(&time_left) < TIME_WARNING)
666 /* yes, we are in hurry
667 stop the herring_song, prepare to play the correct
670 current_music = HURRYUP_MUSIC;
674 current_music = LEVEL_MUSIC;
677 /* stop the old music if it's being played */
682 /* Handle skidding: */
684 timer_check(&pplayer->skidding_timer);
688 if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
695 int player_on_ground(player_type *pplayer)
697 if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height + 1) ||
698 issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height + 1) ||
699 issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height + 1) )
709 void player_handle_horizontal_input(player_type *pplayer, int dir)
711 if (pplayer->jumping == NO)
713 if ((dir ? (pplayer->base.xm < -SKID_XM) : (pplayer->base.xm > SKID_XM)) && !timer_started(&pplayer->skidding_timer) &&
714 pplayer->dir == !dir)
716 timer_start(&pplayer->skidding_timer, SKID_TIME);
718 play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
724 if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + 32) &&
725 !timer_started(&pplayer->skidding_timer))
727 pplayer->base.xm = 0;
732 if (pplayer->dir == dir)
734 /* Facing the direction we're jumping? Go full-speed: */
736 if (pplayer->input.fire == UP)
738 pplayer->base.xm = pplayer->base.xm + ( dir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
742 if (pplayer->base.xm > MAX_WALK_XM)
743 pplayer->base.xm = MAX_WALK_XM;
747 if (pplayer->base.xm < -MAX_WALK_XM)
748 pplayer->base.xm = -MAX_WALK_XM;
751 else if ( pplayer->input.fire == DOWN)
753 pplayer->base.xm = pplayer->base.xm + ( dir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
757 if (pplayer->base.xm > MAX_RUN_XM)
758 pplayer->base.xm = MAX_RUN_XM;
762 if (pplayer->base.xm < -MAX_RUN_XM)
763 pplayer->base.xm = -MAX_RUN_XM;
768 /* Not facing the direction we're jumping?
771 pplayer->base.xm = pplayer->base.xm + ( dir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
775 if (pplayer->base.xm > MAX_WALK_XM / 2)
776 pplayer->base.xm = MAX_WALK_XM / 2;
780 if (pplayer->base.xm < -MAX_WALK_XM / 2)
781 pplayer->base.xm = -MAX_WALK_XM / 2;
789 void player_handle_vertical_input(player_type *pplayer)
791 if(pplayer->input.up == DOWN)
793 if (player_on_ground(pplayer))
795 if(!physic_is_set(&pplayer->vphysic))
797 physic_set_state(&pplayer->vphysic,PH_VT);
798 physic_set_start_vy(&pplayer->vphysic,5.5);
800 pplayer->jumping = YES;
801 if (pplayer->size == SMALL)
802 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
804 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
808 else if(pplayer->input.up == UP && pplayer->jumping == YES)
811 DEBUG_MSG("Stop Jump");
812 pplayer->jumping = NO;
814 if (pplayer->base.ym > 0)
816 pplayer->base.y = (int)(pplayer->base.y / 32) * 32;
817 pplayer->base.ym = 0;
819 physic_init(&pplayer->vphysic);
821 else if(pplayer->input.up == UP)
823 if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
825 physic_init(&pplayer->vphysic);
826 pplayer->jumping == NO;
830 pplayer->jumping = NO;
831 printf("%f",physic_get_velocity(&pplayer->vphysic));
832 if(physic_is_set(&pplayer->vphysic))
834 if(physic_get_velocity(&pplayer->vphysic) < 0.)
836 physic_set_state(&pplayer->vphysic,PH_VT);
837 DEBUG_MSG("DUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDE");
838 physic_set_start_vy(&pplayer->vphysic,0);
843 DEBUG_MSG("CHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUHHHHAAA");
844 if(!physic_is_set(&pplayer->vphysic))
846 DEBUG_MSG("CHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUHHHHAAA");
847 physic_set_state(&pplayer->vphysic,PH_VT);
855 if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
856 pplayer->base.ym != 0)
858 /* If they're not on the ground, or are currently moving
859 vertically, don't jump! * /
861 pplayer->jumping = NO;
862 timer_stop(&pplayer->jump_timer);
866 /* Make sure we're not standing back up into a solid! * /
868 if (pplayer->size == SMALL || pplayer->duck == NO ||
869 !issolid(pplayer->base.x, pplayer->base.y))
871 pplayer->jumping = YES;
873 if (pplayer->size == SMALL)
874 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
876 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
880 /* Keep jumping for a while: * /
882 if (timer_check(&pplayer->jump_timer))
884 pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
885 if (pplayer->base.ym < -YM_FOR_JUMP)
886 pplayer->base.ym = pplayer->base.ym/*-YM_FOR_JUMP* /;
890 void player_input(player_type *pplayer)
892 /* Handle key and joystick state: */
895 if (pplayer->input.right == DOWN && pplayer->input.left == UP)
897 player_handle_horizontal_input(pplayer,RIGHT);
899 else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
901 player_handle_horizontal_input(pplayer,LEFT);
905 if(pplayer->base.xm > 0)
906 pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio);
907 else if(pplayer->base.xm < 0)
908 pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio);
913 if ( pplayer->input.up == DOWN || (pplayer->input.up == UP && pplayer->jumping == YES))
915 player_handle_vertical_input(pplayer);
920 if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
922 add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
928 if (pplayer->input.down == DOWN)
930 if (pplayer->size == BIG)
935 if (pplayer->size == BIG && pplayer->duck == YES)
937 /* Make sure we're not standing back up into a solid! */
939 if (!issolid(pplayer->base.x + 16, pplayer->base.y - 16))
948 if (pplayer->input.right == UP && pplayer->input.left == UP)
950 pplayer->frame_main = 1;
955 if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
957 pplayer->frame_main = (pplayer->frame_main + 1) % 4;
959 pplayer->frame = pplayer->frame_main;
961 if (pplayer->frame == 3)
967 void player_grabdistros(player_type *pplayer)
972 trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
973 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
975 trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
976 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
978 if(pplayer->size == BIG)
980 trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
981 trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
987 /* Enough distros for a One-up? */
989 if (distros >= DISTROS_LIFEUP)
991 distros = distros - DISTROS_LIFEUP;
992 if(pplayer->lives < MAX_LIVES)
994 /*We want to hear the sound even, if MAX_LIVES is reached*/
995 play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
999 void player_draw(player_type* pplayer)
1001 if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
1003 if (pplayer->size == SMALL)
1005 if (timer_started(&pplayer->invincible_timer))
1009 if (pplayer->dir == RIGHT)
1011 texture_draw(&cape_right[frame % 2],
1012 pplayer->base.x- scroll_x, pplayer->base.y,
1017 texture_draw(&cape_left[frame % 2],
1018 pplayer->base.x- scroll_x, pplayer->base.y,
1024 if (!pplayer->got_coffee)
1026 if (pplayer->dir == RIGHT)
1028 texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1032 texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1037 /* Tux got coffee! */
1039 if (pplayer->dir == RIGHT)
1041 texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1045 texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1051 if (timer_started(&pplayer->invincible_timer))
1055 if (pplayer->dir == RIGHT)
1057 texture_draw(&bigcape_right[frame % 2],
1058 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1063 texture_draw(&bigcape_left[frame % 2],
1064 pplayer->base.x-scroll_x - 8, pplayer->base.y,
1069 if (!pplayer->got_coffee)
1073 if (!timer_started(&pplayer->skidding_timer))
1075 if (!pplayer->jumping || pplayer->base.ym > 0)
1077 if (pplayer->dir == RIGHT)
1079 texture_draw(&bigtux_right[pplayer->frame],
1080 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1085 texture_draw(&bigtux_left[pplayer->frame],
1086 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1092 if (pplayer->dir == RIGHT)
1094 texture_draw(&bigtux_right_jump,
1095 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1100 texture_draw(&bigtux_left_jump,
1101 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1108 if (pplayer->dir == RIGHT)
1110 texture_draw(&skidtux_right,
1111 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1116 texture_draw(&skidtux_left,
1117 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1124 if (pplayer->dir == RIGHT)
1126 texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1131 texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1138 /* Tux has coffee! */
1142 if (!timer_started(&pplayer->skidding_timer))
1144 if (!pplayer->jumping || pplayer->base.ym > 0)
1146 if (pplayer->dir == RIGHT)
1148 texture_draw(&bigfiretux_right[pplayer->frame],
1149 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1154 texture_draw(&bigfiretux_left[pplayer->frame],
1155 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1161 if (pplayer->dir == RIGHT)
1163 texture_draw(&bigfiretux_right_jump,
1164 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1169 texture_draw(&bigfiretux_left_jump,
1170 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1177 if (pplayer->dir == RIGHT)
1179 texture_draw(&skidfiretux_right,
1180 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1185 texture_draw(&skidfiretux_left,
1186 pplayer->base.x- scroll_x - 8, pplayer->base.y,
1193 if (pplayer->dir == RIGHT)
1195 texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1200 texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1209 void player_collision(player_type* pplayer, void* p_c_object, int c_object)
1211 bad_guy_type* pbad_c = NULL;
1216 pbad_c = (bad_guy_type*) p_c_object;
1217 /* Hurt the player if he just touched it: */
1219 if (!pbad_c->dying && !pplayer->dying &&
1220 !timer_started(&pplayer->safe_timer) &&
1221 pbad_c->mode != HELD)
1223 if (pbad_c->mode == FLAT && pplayer->input.fire != DOWN)
1227 pbad_c->mode = KICK;
1228 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1230 if (pplayer->base.x<= pbad_c->base.x)
1232 pbad_c->dir = RIGHT;
1233 pbad_c->base.x = pbad_c->base.x + 16;
1238 pbad_c->base.x = pbad_c->base.x - 16;
1241 timer_start(&pbad_c->timer,5000);
1243 else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
1245 pbad_c->mode = HELD;
1248 else if (pbad_c->mode == KICK)
1250 if (pplayer->base.y < pbad_c->base.y - 16 &&
1251 timer_started(&pbad_c->timer))
1253 /* Step on (stop being kicked) */
1255 pbad_c->mode = FLAT;
1256 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1257 timer_start(&pbad_c->timer, 10000);
1261 /* Hurt if you get hit by kicked laptop: */
1263 if (timer_started(&pbad_c->timer))
1265 if (!timer_started(&pplayer->invincible_timer))
1267 player_kill(pplayer,SHRINK);
1271 pbad_c->dying = FALLING;
1272 pbad_c->base.ym = -8;
1273 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1280 if (!timer_started(&pplayer->invincible_timer ))
1282 player_kill(pplayer,SHRINK);
1286 pbad_c->dying = FALLING;
1287 pbad_c->base.ym = -8;
1288 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1302 void player_kill(player_type* pplayer, int mode)
1304 pplayer->base.ym = -5;
1306 play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
1308 if (pplayer->dir == RIGHT)
1309 pplayer->base.xm = -8;
1310 else if (pplayer->dir == LEFT)
1311 pplayer->base.xm = 8;
1313 if (mode == SHRINK && pplayer->size == BIG)
1315 if (pplayer->got_coffee)
1316 pplayer->got_coffee = NO;
1318 pplayer->size = SMALL;
1319 pplayer->base.height = 32;
1321 timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
1329 void player_dying(player_type *pplayer)
1331 pplayer->base.ym = pplayer->base.ym + gravity;
1336 player_remove_powerups(pplayer);
1337 pplayer->dying = NO;
1339 player_level_begin(pplayer);
1343 /* Remove Tux's power ups */
1344 void player_remove_powerups(player_type* pplayer)
1346 pplayer->got_coffee = NO;
1347 pplayer->size = SMALL;
1348 pplayer->base.height = 32;
1351 void player_keep_in_bounds(player_type* pplayer)
1353 /* Keep tux in bounds: */
1354 if (pplayer->base.x< 0)
1356 else if(pplayer->base.x< scroll_x)
1357 pplayer->base.x= scroll_x;
1358 else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
1360 scroll_x = pplayer->base.x- 160;
1361 /*pplayer->base.x+= 160;*/
1367 else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
1369 /* Scroll the screen in past center: */
1371 scroll_x = pplayer->base.x- screen->w / 2;
1372 /*pplayer->base.x= 320 + scroll_x;*/
1374 if (scroll_x > ((current_level.width * 32) - screen->w))
1375 scroll_x = ((current_level.width * 32) - screen->w);
1377 else if (pplayer->base.x> 608 + scroll_x)
1379 /* ... unless there's no more to scroll! */
1381 /*pplayer->base.x= 608 + scroll_x;*/
1384 /* Keep in-bounds, vertically: */
1386 if (pplayer->base.y < 0)
1387 pplayer->base.y = 0;
1388 else if (pplayer->base.y > screen->h)
1390 player_kill(&tux,KILL);