View Game: In The Dark 4K

In The Dark 4K (http://gef4k.tumblr.com/)

By Gef, submitted on Jan 3, 2014
Min JRE version: 1.6
10349 downloads.
This game was submitted in the Java4K 2014 Competition.
Source code available! Show source code

(Click on game for focus)


You need Java installed to play this game.
You may use the button below to get it.

Get Java


Description

After being captured by the ghosts of last year, our sorcerer has been locked in a jail in the basements of the witch’s castle. After several months, he decides to escape. He can still shoot fireballs. And, because of the darkness, he uses a spell which produces a light above him, but it runs out over time. To revive it, he needs to kill creatures. So pay attention to his intensity...

To go upstairs through the 5 levels, he has to collect the coins scattered all over each one.

Good luck !

Instructions

The UI
- green bar is for life level
- white bar is for light intensity
- on the right, the number of coins to collect in the current level

Game Controls
- Move : Arrow keys
- Jump : SPACE
- Fire : W
- Pause : P
- Start/continue : ENTER

The player can move freely, but when you start shooting, the shooting direction locks until you release the fire key.

User Comments

Total 3 comments:

#1 By kles4enko Feb 20, 2014 at 10:48:34
Awesome! How do you create this?! Can recommend any book? :)
#2 By Gef Mar 1, 2014 at 04:20:43
Thanks ! I don\'t know books about voxels, but Google helped me a lot. Come on Java-Gaming.org, there are lot of discussions on cube world and used techniques.
#3 By Wircea May 29, 2014 at 10:01:42
Wow, very impressing. I mean, a fully functional lighting system? cool graphics? Under 4 kb? Hats off.

You need be logged in to write comments. If you need to register click here.

Source code

Note: We recommend you copy+paste this to a better editor. Some special character encoding may have been lost.

entities, int type, int x, int y, int z, int dirX, int dirY, int dirZ, int model, int angle, int life, int fx, int fy, int fz, int animSpeed) { entities.add( new int[] { // TYPE type, // X, Y, Z x < 8,="" y="">< 8,="" z="">< 8,="" dirx,="" diry,="" dirz="" dirx="">< 8,="" diry="">< 8,="" dirz="">< 8,="" model,="" angle="" model,="" angle="">< 8,="" touch_ground="" 0,="" life="" life,="" forcex,="" forcey,="" forcez="" fx="">< 8,="" fy="">< 8,="" fz="">< 8,="" animation_speed="" animspeed="">< 8="" }="" );="" }="" @override="" public="" void="" run()="" {="" final="" boolean="" debug="false;" rendering="" constants="" final="" int="" screen_width="672;" final="" int="" screen_height="600;" final="" int="" world_size_x="1024;" final="" int="" world_size_y="29;" final="" int="" world_size_z="1024;" final="" int="" frustum_size="84;" final="" int="" block_x="4;" final="" int="" block_y="3;" final="" int="" light_distance="84;" final="" int="" pcf_shadow="10;" entity="" types="" final="" int="" entity_player_type="0;" final="" int="" entity_eneny_type="1;" final="" int="" entity_bullet_type="2;" final="" int="" entity_object_type="3;" final="" int="" entity_block_type="4;" model="" angles="" final="" int="" front_angle="0;" final="" int="" left_angle="1;" final="" int="" back_angle="2;" final="" int="" right_angle="3;" motion="" constants="" final="" int="" gravity="64000;"><8; final="" int="" player_speed="15360;"></8;><8; final="" int="" player_jump="25600;"></8;><8; final="" int="" object_jump="38400;"></8;><8; final="" int="" bullet_speed="100;" will="" be="" transformed="" in="" fixed="" int="" by="" addentity(...)="" final="" int="" enemy_speed="6400;"></8;><8; final="" int="" explosion_radius="10;" final="" int="" explosion_radius_force="10;" final="" int="" step_height="5;" final="" int="" min_moving_distance="6553600;"></8;><><8) delta="" used="" to="" verify="" if="" entity="" is="" moving;="" entity="" attributes="" final="" int="" type="0;" final="" int="" x="1;" final="" int="" y="2;" final="" int="" z="3;" final="" int="" dirx="4;" final="" int="" diry="5;" final="" int="" dirz="6;" final="" int="" model="7;" final="" int="" angle="8;" final="" int="" touch_ground="9;" final="" int="" life="10;" final="" int="" forcex="11;" final="" int="" forcey="12;" final="" int="" forcez="13;" final="" int="" animation_speed="14;" block="" types="" final="" int="" block_transparent="0;" final="" int="" block_ephemeral="1;" final="" int="" block_decor="2;" final="" int="" block_entity="3;" final="" int="" block_solid="4;" final="" int="" block_type_shift="4;" final="" int="" block_value_bitmask="15;" game="" status="" final="" int="" generate_map="0;" final="" int="" playing="1;" final="" int="" pause="2;" final="" int="" next_level="3;" final="" int="" you_loose="4;" final="" int="" you_win="5;" keyboard="" values="" final="" int="" key_enter="10;" final="" int="" key_space="32;" final="" int="" key_p="112;" final="" int="" key_w="119;" final="" int="" key_up="1004;" final="" int="" key_down="1005;" final="" int="" key_left="1006;" final="" int="" key_right="1007;" entity="" models="" final="" int="" model_buzz_enemy="2;" final="" int="" model_blob_enemy="3;" final="" int="" model_heart="4;" final="" int="" model_ground="5;" final="" int="" model_wall="6;" final="" int="" model_coin="7;" maze="" generation="" final="" int="" cell_size="64;" final="" int="" min_wall_size="4;" color="" panel="" final="" string="" string_colors="\u0080\u00FF\u0000" +="" "\u00ef\u00e4\u00b0"="" +="" "\u0000\u0040\u0000"="" +="" "\u00ff\u00ff\u00ff"="" +="" "\u00ff\u00ff\u0000"="" +="" "\u00ff\u0080\u0000"="" +="" "\u0000\u00ff\u0000"="" +="" "\u00ff\u0000\u0000"="" +="" "\u00ff\u0080\u00ff"="" +="" "\u0080\u0080\u0080"="" +="" "\u00ff\u0000\u00ff"="" +="" "\u00c0\u00c0\u00c0";="" levels="" final="" string="" string_levels="\u0004\u0004\u001C\u001C" +="" "\u0002\u0003\u0005\u0000"="" +="" "\u0000\u0000\u000e\u0001"="" +="" "\u0006\u0001\f\u0000"="" +="" "\n\u0003\u000b\u0001"="" +="" "\u0005"="" +="" "\u0006\u0003\u00dc\u001c"="" +="" "\u0002\u0007\u0001"="" +="" "\u0000\f\u0004"="" +="" "\u0006\u000b\t"="" +="" "\n\u0005\u0000"="" +="" "\u0006\t\u0000"="" +="" "\n\u0003\u0001"="" +="" "\u0006"="" +="" "\u0007\u0007\u011c\u001c"="" +="" "\u0000\u0006\u0007\u0003\u0007\u0005\u0000"="" +="" "\u0006\t\u000e\u0003\r\n\u0005"="" +="" "\u000e\u0007\t\u0000\n\u0007\r"="" +="" "\f\f\u0000\u0000\u0000\f\f"="" +="" "\u000e\u000b\u0005\u0000\u0006\u000b\r"="" +="" "\n\u0005\u000e\u0003\r\u0006\t"="" +="" "\u0000\n\u000b\u0003\u000b\t\u0000"="" +="" "\u000c"="" +="" "\n\u0005\u009c\u001c"="" +="" "\u0006\u0001\u0000\u0000\u0000"="" +="" "\n\u0005\u0004\u0006\u0005"="" +="" "\u0006\t\n\t\f"="" +="" "\f\u0000\u0006\u0005\f"="" +="" "\u000e\u0003\r\u000e\r"="" +="" "\b\u0000\n\t\f"="" +="" "\u0000\u0004\u0000\u0004\f"="" +="" "\u0006\r\u0006\u000b\t"="" +="" "\b\f\u000e\u0001\u0000"="" +="" "\u0000\n\t\u0000\u0000"="" +="" "\u000c"="" +="" "\n\n\u015c\u011c"="" +="" "\u0000\u0000\u0004\u0006\u0001\u0000\u0000\u0004\u0000\u0000"="" +="" "\u0000\u0000\u000e\u000b\u0001\u0000\u0004\u000e\u0001\u0000"="" +="" "\u0002\u0005\u000e\u0007\u0003\u0003\u000b\u000f\u0007\u0001"="" +="" "\u0006\t\f\f\u0000\u0000\u0002\r\b\u0000"="" +="" "\n\u0003\r\f\u0004\u0004\u0000\f\u0000\u0000"="" +="" "\u0000\u0006\t\b\n\u000b\u0003\r\u0006\u0005"="" +="" "\u0006\u000b\u0003\u0003\u0001\u0000\u0000\u000e\t\b"="" +="" "\u000e\u0005\u0000\u0004\u0004\u0004\u0004\f\u0000\u0000"="" +="" "\f\n\u0003\u000b\u000f\u000b\r\u000e\u0001\u0004"="" +="" "\n\u0003\u0001\u0000\b\u0000\n\u000b\u0003\t"="" +="" "\u0026";="" models="" final="" string="" string_objects="//" player="" "\u000b\u000b\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0033\u0033\u0033\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0034\u0031\u0031\u0033\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0031\u0000\u0031\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0032\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0033\u0033\u0033\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0031\u0031\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"="" +="" bullet="" "\u0003\u0003\u0004\u0000\u0015\u0000\u0000\u0015\u0016\u0016\u0015\u0000\u0015\u0000\u0000\u0015\u0015\u0015\u0000\u0015\u0015\u0016\u0016\u0015\u0016\u0015\u0000\u0000\u0015\u0000\u0000\u0015\u0016\u0015\u0000\u0000\u0015\u0000\u0000"="" +="" buzz="" "\u0007\b\u0005\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0036\u0000\u0032\u0000\u0000\u0000\u0032\u0032\u0000\u0000\u0036\u0036\u0000\u0000\u0000\u0037\u0036\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0036\u0036\u0000\u0000\u0000\u0036\u0036\u0000\u0000\u0000\u0036\u0036\u0038\u0000\u0036\u0036\u0036\u0038\u0000\u0000\u0036\u0036\u0038\u0000\u0038\u0038\u0038\u0000\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0036\u0000\u0032\u0000\u0000\u0000\u0032\u0032\u0000\u0000\u0036\u0036\u0000\u0000\u0000\u0037\u0036\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0036\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0032\u0000\u0000\u0000\u0000\u0000"="" +="" blob="" "\u0006\u0006\u0007\u0000\u0000\u0000\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0000\u0000\u0000\u0000\u0000\u0039\u0000\u0000\u0000\u0000\u0000\u0000\u0039\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0039\u0039\u0000\u0000\u0039\u0000\u0039\u0039\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0034\u0039\u0039\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0039\u0039\u0039\u0039\u0039\u0000\u0000\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0000\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0039\u0039\u0039\u0000\u0039\u0039\u0039\u0039\u0039\u0000\u0000\u0039\u0039\u0039\u0039\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0034\u0039\u0039\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0039\u0039\u0039\u0000\u0000\u0000\u0000\u0039\u0039\u0000\u0000\u0000\u0000\u0000\u0039\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"="" +="" heart="" "\u0007\u0006\u0003\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000\u0000\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0000\u0038\u0038\u0000\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0038\u0038\u0000\u0038\u0038\u0000\u0000\u0000"="" +="" ground="" "\b\u0001\b\u002a\u002a\u002a\u0000\u0000\u002a\u002a\u002a\u002a\u002a\u0000\u002a\u002a\u0000\u002a\u002a\u002a\u0000\u002a\u002a\u002a\u002a\u0000\u002a\u0000\u002a\u002a\u002a\u002a\u002a\u002a\u0000\u0000\u002a\u002a\u0000\u002a\u002a\u002a\u0000\u002a\u0000\u002a\u002a\u002a\u002a\u0000\u002a\u002a\u002a\u0000\u002a\u002a\u0000\u002a\u002a\u0000\u002a\u002a\u0000\u0000\u002a\u002a\u002a"="" +="" wall="" "\f\f\u0001\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\u0000\u0000\u0000\u0000\u0000\"\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\"\"\"\u0000\u0000\u0000\"\"\u0000\u0000\u0000\"\"\"\"\u0000\u0000\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\u0000\u0000\u0000\u0000\u0000\"\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\"\"\"\"\u0000\u0000\u0000\"\"\u0000\u0000\u0000\"\"\"\"\u0000\u0000\"\"\"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\""="" +="" coin="" "\u0005\u0005\u0002\u0000\u0000\u0000\u0035\u0000\u0035\u0000\u0035\u0000\u0000\u0000\u0035\u0035\u0035\u0035\u0035\u0035\u0035\u0000\u0035\u0000\u0035\u0035\u0035\u0035\u0035\u0035\u0035\u0000\u0035\u0000\u0035\u0035\u0035\u0035\u0035\u0035\u0035\u0000\u0035\u0000\u0000\u0000\u0035\u0000\u0035\u0000\u0035\u0000\u0000";="" level="" map="" final="" byte[][][]="" box="new" byte[world_size_x][world_size_y][world_size_z];="" models="" array="" final="" byte[][][][][]="" models="new" byte[8][][][][];="" color="" array="" final="" int[]="" colors="new" int[light_distance="" *="" 16];="" maze="" array="" byte[][]="" maze="null;" screen="" manipulation="" final="" bufferedimage="" screen="new" bufferedimage(screen_width,="" screen_height,="" bufferedimage.type_int_rgb);="" final="" int[]="" pixels="((DataBufferInt)" screen.getraster().getdatabuffer()).getdata();="" final="" graphics="" gfx="screen.getGraphics();" graphics="" appletgraphics="null;" entities="" collection=""></8)> entities = null; // Other variables int map_size_x = 0; int map_size_z = 0; int tick = 0; int fps = 0; int acc = 0; int mazeWidth = 0; int mazeHeight = 0; int level = 1; int nbEnemies = 0; int nbEnemiesToPop = 0; int i = 0; int j = 0; int k = 0; int l = 0; int frustumX = 0; int frustumZ = 0; int playerLife = 0; int playerX = 0; int playerZ = 0; int gameState = 0; int lightStrength = 0; int nbCoins = 0; long lastFrame = 0; long nextBullet = 0; long nextLightVariation = 0; /******************* * Initialisations * *******************/ if (DEBUG) { setSize(SCREEN_WIDTH, SCREEN_HEIGHT); requestFocus(); } // Color panel k = LIGHT_DISTANCE; char[] c = STRING_COLORS.toCharArray(); for (i = 0; i < c.length;="" i="" +="3)" {="" for="" (j="LIGHT_DISTANCE" -="" 1;="" j="">= 0; j--) { float coef = 1 - 1 / ((j / (float) (LIGHT_DISTANCE - 1) + 1) * (j / (float) (LIGHT_DISTANCE - 1) + 1)); colors[k++] = ((int) (c[i] * coef) < 16)="" +="" ((int)="" (c[i="" +="" 1]="" *="" coef)="">< 8)="" +="" (int)="" (c[i="" +="" 2]="" *="" coef);="" }="" }="" models="" collection="" c="STRING_OBJECTS.toCharArray();" int="" n="0;" for="" (l="0;" l="">< c.length;)="" {="" model="" dimensions="" int="" x="c[l];" int="" y="c[l" +="" 1];="" int="" z="c[l" +="" 2];="" l="" +="3;" initialise="" the="" 8="" models="" arrays="" :="" 4="" standards="" &="" 4="" variants="" models[n]="new" byte[][][][]="" {="" 4="" standards="" front="" new="" byte[x][y][z],="" left="" new="" byte[z][y][x],="" back="" new="" byte[x][y][z],="" right="" new="" byte[z][y][x],="" 4="" variants="" used="" for="" animation="" front="" new="" byte[x][y][z],="" left="" new="" byte[z][y][x],="" back="" new="" byte[x][y][z],="" right="" new="" byte[z][y][x]="" };="" filling="" of="" models="" arrays="" for="" (i="0;" i="">< x;="" i++)="" {="" for="" (j="0;" j="">< y;="" j++)="" {="" for="" (k="0;" k="">< z;="" k++,="" l++)="" {="" byte[][][][]="" model="models[n];" int="" x1="x" -="" i="" -="" 1;="" int="" z1="z" -="" k="" -="" 1;="" front="" model[front_angle][i][j][k]="model[FRONT_ANGLE" +="" 4][x1][j][k]="//" back="" model[back_angle][x1][j][z1]="model[BACK_ANGLE" +="" 4][i][j][z1]="//" right="" model[left_angle][k][j][x1]="model[LEFT_ANGLE" +="" 4][k][j][i]="//" left="" model[right_angle][z1][j][i]="model[RIGHT_ANGLE" +="" 4][z1][j][x1]="(byte)" c[l];="" }="" }="" }="" n++;="" }="" ************="" *="" game="" loop="" *="" *************/="" while="" (true)="" {="" long="" now="System.nanoTime();" gfx.clearrect(0,="" 0,="" screen_width,="" screen_height);="" if="" (gamestate="=" generate_map)="" {="" loading="" of="" the="" next="" level="" reset="" some="" variables="" if=""><5) playerlife="5;" lightstrength="LIGHT_DISTANCE-1;" nbcoins="0;" nbenemies="0;" gamestate="NEXT_LEVEL;" c="STRING_LEVELS.toCharArray();" loop="" to="" find="" the="" current="" level="" l="1;" k="0;" while="" (l=""></5)>< level)="" {="" k="" +="(c[k]" *="" c[k="" +="" 1]="" +="" 5);="" l++;="" }="" mazewidth="c[k];" mazeheight="c[k" +="" 1];="" playerx="c[k" +="" 2];="" playerz="c[k" +="" 3];="" initialise="" entities="" list="" with="" just="" the="" player="" entities="new">(); addEntity( entities, // TYPE ENTITY_PLAYER_TYPE, // X, Y, Z playerX, 18, playerZ, // DIRX, DIRY, DIRZ 0, 0, 0, // MODEL, ANGLE 0, 2, // LIFE playerLife, // FORCEX, FORCEY, FORCEZ 0, 0, 0, // ANIMATION_SPEED 10); // Reading of the maze maze = new byte[mazeWidth][mazeHeight]; for (i = 0; i < mazewidth;="" i++)="" {="" for="" (j="0;" j="">< mazeheight;="" j++,="" k++)="" {="" byte="" cell="maze[i][j]" =="" (byte)="" c[k="" +="" 4];="" if="" the="" current="" cell="" is="" not="" filled,="" add="" a="" coin="" in="" it="" if="" (cell=""> 0 && (i != playerX / CELL_SIZE || j != playerZ / CELL_SIZE)) { nbCoins++; addEntity( entities, // TYPE ENTITY_OBJECT_TYPE, // X, Y, Z i * CELL_SIZE + CELL_SIZE / 2, 15, j * CELL_SIZE + CELL_SIZE / 2, // DIRX, DIRY, DIRZ 0, 0, 0, // MODEL, ANGLE MODEL_COIN, 0, // LIFE 1, // FORCEX, FORCEY, FORCEZ 0, 0, 0, // ANIMATION_SPEED 0); } } } nbEnemiesToPop = c[k+4]; // Creation of the voxelbox based on the maze map_size_x = mazeWidth * CELL_SIZE; map_size_z = mazeHeight * CELL_SIZE; for (i = 0; i < map_size_x;="" i++)="" {="" for="" (j="0;" j="">< map_size_z;="" j++)="" {="" byte="" cell="maze[i" cell_size][j="" cell_size];="" boolean="" murnord="(cell" &="" 1)="=" 0;="" boolean="" mursud="(cell" &="" 2)="=" 0;="" boolean="" murest="(cell" &="" 4)="=" 0;="" boolean="" murouest="(cell" &="" 8)="=" 0;="" int="" x1="murOuest" min_wall_size="" :="" 0;="" int="" x2="murEst" cell_size="" -="" min_wall_size="" :="" cell_size;="" int="" z1="murNord" min_wall_size="" :="" 0;="" int="" z2="murSud" cell_size="" -="" min_wall_size="" :="" cell_size;="" for="" (int="" y="WORLD_SIZE_Y" -="" 1;="" y="">= 0; y--) { // Default block = unbreakable wall byte block = ((BLOCK_SOLID < block_type_shift)="" +="" 10);="" if="" cell="" is="" open="" if="" (cell=""> 0) { // Default block = breakable wall block = ((BLOCK_DECOR < block_type_shift)="" +="" 12);="" if="" (y=""><= 5)="" {="" ground="" \="" tile="" \="" block="y"></=>< 4="" (block_decor="">< block_type_shift)="" +="" 10="" :="" models[model_ground][0][i="" %="" 8][0][j="" %="" 8];="" }="" else="" {="" determine="" walls="" int="" x="i" -="" (i="" cell_size)="" *="" cell_size;="" int="" z="j" -="" (j="" cell_size)="" *="" cell_size;="" if="" (x="">= x1 && x < x2="" &&="" z="">= z1 && z < z2)="" {="" block="0;" if="" ((murnord="" &&="" z="=" z1)="" ||="" (mursud="" &&="" z="=" z2="" -="" 1))="" block="models[MODEL_WALL][0][i" %="" 12][y="" %="" 12][0];="" if="" ((murouest="" &&="" x="=" x1)="" ||="" (murest="" &&="" x="=" x2="" -="" 1))="" block="models[MODEL_WALL][1][0][y" %="" 12][j="" %="" 12];="" }="" }="" }="" box[i="" +="" 1][y][j="" +="" 1]="block;" }="" }="" }="" }="" calculate="" time="" elapsed="" since="" the="" last="" frame="" float="" timeelapsed="(int)(now" -="" lastframe)="" 1000000000f;="" if="" (timeelapsed=""> 0.1f) { timeElapsed = 0.1f; } if (DEBUG) { // Fps counter acc += now - lastFrame; tick++; if (acc >= 1000000000L) { acc -= 1000000000L; fps = tick; tick = 0; } } lastFrame = now; // Friction for this frame float friction = 0.85f * (1 - timeElapsed); // Loop through the entities list for (int e = entities.size() - 1; e >= 0; e--) { int[] entity = entities.get(e); int entityType = entity[TYPE]; // Store some variables byte[][][] model = null; int x = entity[X] >> 8; int y = entity[Y] >> 8; int z = entity[Z] >> 8; int dx = entity[DIRX]; int dy = entity[DIRY]; int dz = entity[DIRZ]; boolean firing = false; // Model & Dimensions int sx = 1; int sy = 1; int sz = 1; if (entityType < entity_block_type)="" {="" model="models[entity[MODEL]][entity[ANGLE]">> 8]; sx = model.length; sy = model[0].length; sz = model[0][0].length; } // Clear entity at current position for (i = x; i < x="" +="" sx;="" i++)="" {="" for="" (j="y;" j="">< y="" +="" sy;="" j++)="" {="" for="" (k="z;" k="">< z="" +="" sz;="" k++)="" {="" if="" ((box[i][j][k]="">> BLOCK_TYPE_SHIFT) > BLOCK_TRANSPARENT) { box[i][j][k] = 0; } } } } // Player related modifications if (entityType == ENTITY_PLAYER_TYPE) { dx = 0; dz = 0; playerX = x + 5; playerZ = z + 6; if (gameState == PLAYING) { if (keys[KEY_UP]) { dz = PLAYER_SPEED; } if (keys[KEY_DOWN]) { dz = -PLAYER_SPEED; } if (keys[KEY_LEFT]) { dx = -PLAYER_SPEED; } if (keys[KEY_RIGHT]) { dx = PLAYER_SPEED; } if (keys[KEY_SPACE] && entity[TOUCH_GROUND] == 1) { dy = PLAYER_JUMP; } if (keys[KEY_P]) { gameState = PAUSE; } firing = keys[KEY_W]; // Light Variation if (now >= nextLightVariation) { lightStrength--; nextLightVariation = now + 1000000000L; } } } // Enemy direction if (entityType == ENTITY_ENENY_TYPE) { dx = playerX - x; dz = playerZ - z; int sqrt = (ENEMY_SPEED<8) ((int)="" math.sqrt(dx="" *="" dx="" +="" dz="" *="" dz)="" +="" 1);="" dx="(dx" *="" sqrt)="">>8; dz = (dz * sqrt)>>8; } // Object jump if (entityType == ENTITY_OBJECT_TYPE && entity[TOUCH_GROUND] == 1) { dy += OBJECT_JUMP; } // Friction & Gravity if (entityType != ENTITY_BULLET_TYPE) { // Friction dx *= friction; dy *= friction; dz *= friction; // Gravity dy -= GRAVITY * timeElapsed; } // Determine variant & direction for the model if (entityType < entity_object_type)="" {="" i="j" =="" entity[angle]="">> 8; if (dz * dz > dx * dx) { if (dz > 0) { i = BACK_ANGLE; } if (dz < 0)="" {="" i="FRONT_ANGLE;" }="" }="" else="" {="" if="" (dx=""> 0) { i = RIGHT_ANGLE; } if (dx < 0)="" {="" i="LEFT_ANGLE;" }="" }="" entity[angle]="" +="(int)(entity[ANIMATION_SPEED]*timeElapsed);" if="" (j="" !="(entity[ANGLE]">> 8)) { entity[ANGLE] = ((j + 4) & 7) < 8;="" }="" if="" (!(firing="" ||="" i="=" ((entity[angle]="">> 8) & 3))) { entity[ANGLE] = i < 8;="" }="" }="" friction="" on="" external="" force="" entity[forcex]="" *="friction;" entity[forcey]="" *="friction;" entity[forcez]="" *="friction;" add="" external="" force="" dx="" +="entity[FORCEX];" dy="" +="entity[FORCEY];" dz="" +="entity[FORCEZ];" save="" new="" direction="" entity[dirx]="dx;" entity[diry]="dy;" entity[dirz]="dz;" move="" for="" this="" frame="" dx="" *="timeElapsed;" dy="" *="timeElapsed;" dz="" *="timeElapsed;" new="" model="" &="" dimensions="" int="" decal="0;" if="" (entitytype="">< entity_block_type)="" {="" model="models[entity[MODEL]][entity[ANGLE]">> 8]; sx = model.length; sy = model[0].length; sz = model[0][0].length; // This variable is used to prevent collisions with the decor when the model as different width or depth decal = -3; } /** * Collision test explanations * * On Y axis * if entity moves down, test is done on blocks that are the lowest on Y in the entity and goes up while a block collide * if entity moves up, test does the same but in the other direction * * On X axis * The principle is the same as for the Y axis, with two differences : * - a entity can climb few blocks (STEP_HEIGHT) * - a collision occurs if the hole in the wall is not large enough (test delta between ceil and floor) */ // Collisions variables boolean collide = false; int cx = -1; int cy = -1; int cz = -1; entity[TOUCH_GROUND] = 0; // Collision test on Y axis // Down if (dy <= 0)="" {="" for="" (j="0;" j="">= (dy >> 8) && !collide; j--) { int j2 = y + j - 1; for (i = x + sx - 1; i >= x && !collide; i--) { for (k = z + sz - 1; k >= z && !collide; k--) { int blockType = box[i][j2][k] >> BLOCK_TYPE_SHIFT; if (blockType > BLOCK_EPHEMERAL && blockType != BLOCK_ENTITY) { entity[TOUCH_GROUND] = 1; cx = i; cy = j2; cz = k; j++; collide = true; } } } } } else { // Up for (j = 0; j <= (dy="">> 8) && !collide; j++) { int j2 = y + j + sy; for (i = x + sx - 1; i >= x && !collide; i--) { for (k = z + sz - 1; k >= z && !collide; k--) { if (j2 >= WORLD_SIZE_Y - 1 || (box[i][j2][k] >> BLOCK_TYPE_SHIFT) > BLOCK_EPHEMERAL) { cx = i; cy = j2; cz = k; j--; collide = true; } } } } } if (collide) { if (entityType == ENTITY_BLOCK_TYPE) { entity[DIRY] *= -1; } dy = j<8; }="" save="" new="" y="" position="" entity[y]="" +="dy;" y="entity[Y]">> 8; if (gameState == PLAYING || entityType > ENTITY_OBJECT_TYPE) { // Collision test on X axis if (dx != 0) { collide = false; // Determine the X direction int x1 = decal; int x2 = (dx >> 8) + 1; int step = 1; if (dx < 0)="" {="" x1="0;" x2="(dx">> 8) - 1; step = -1; } // Loop through the X distance to move for (i = x1; i != x2 && !collide; i += step) { int i2 = 0; if (step < 0)="" {="" i2="x" +="" i="" -="" 1;="" if="" (i2=""><= 0)="" {="" cx="i2;" collide="true;" break;="" }="" }="" else="" {="" i2="x" +="" sx="" +="" i;="" if="" (i2=""></=><= 0)="" continue;="" if="" (i2="">= map_size_x + 1) { cx = i2; collide = true; break; } } int yFloor = y - 1; int yCeil = 100; int blockType = 0; for (j = y + sy * 2 - 1; j >= y; j--) { if (j < world_size_y)="" {="" for="" (k="z" +="" sz="" -="" 1;="" k="">= z; k--) { blockType = box[i2][j][k] >> BLOCK_TYPE_SHIFT; if (blockType > BLOCK_EPHEMERAL) { if (blockType == BLOCK_DECOR) { if (j >= y + sy) { yCeil = j; continue; } else { yFloor = j; j = 0; break; } } else { yFloor = j; yCeil = 100; j = 0; break; } } } } else { yCeil = j; } } if (blockType > 0) { if (blockType == BLOCK_DECOR && entityType < entity_bullet_type="" &&="" yfloor=""><= y="" +="" step_height="" &&="" yceil="">= yFloor + sy) { entity[Y] = (y = yFloor + 1)<8; }="" else="" {="" cx="i2;" cy="yFloor;" cz="k;" i="" -="step;" collide="true;" }="" }="" }="" if="" (collide)="" {="" if="" (entitytype="=" entity_block_type)="" {="" entity[dirx]="" *="-1;" }="" dx=""></8;><8; }="" save="" new="" x="" position="" entity[x]="" +="dx;" x="entity[X]">> 8; } // Collision test on Z axis if (dz != 0) { collide = false; int z1 = decal; int z2 = (dz >> 8) + 1; int step = 1; if (dz < 0)="" {="" z1="0;" z2="(dz">> 8) - 1; step = -1; } // Loop through the Z distance to move for (k = z1; k != z2 && !collide; k += step) { int k2 = 0; if (step < 0)="" {="" k2="z" +="" k="" -="" 1;="" if="" (k2=""><= 0)="" {="" cz="k2;" collide="true;" break;="" }="" }="" else="" {="" k2="z" +="" sz="" +="" k;="" if="" (k2=""></=><= 0)="" continue;="" if="" (k2="">= map_size_z + 1) { cz = k2; collide = true; break; } } int yFloor = y - 1; int yCeil = 100; int blockType = 0; for (j = y + sy * 2 - 1; j >= y; j--) { if (j < world_size_y)="" {="" for="" (i="x" +="" sx="" -="" 1;="" i="">= x; i--) { blockType = box[i][j][k2] >> BLOCK_TYPE_SHIFT; if (blockType > BLOCK_EPHEMERAL) { if (blockType == BLOCK_DECOR) { if (j >= y + sy) { yCeil = j; continue; } else { yFloor = j; j = 0; break; } } else { yFloor = j; yCeil = 100; j = 0; break; } } } } else { yCeil = j; } } if (blockType > 0) { if (blockType == BLOCK_DECOR && entityType < entity_bullet_type="" &&="" yfloor=""><= y="" +="" step_height="" &&="" yceil="">= yFloor + sy) { entity[Y] = (y = yFloor + 1)<8; }="" else="" {="" cx="i;" cy="yFloor;" cz="k2;" k="" -="step;" collide="true;" }="" }="" }="" if="" (collide)="" {="" if="" (entitytype="=" entity_block_type)="" {="" entity[dirz]="" *="-1;" }="" dz=""></8;><8; }="" save="" new="" z="" position="" entity[z]="" +="dz;" z="entity[Z]">> 8; } // If there's a collision and the entity is not a block or a object if (entityType < entity_object_type)="" {="" if="" (cx=""> 0 && cz > 0) { // Collision with a another entity ? collide = false; for (l = entities.size() - 1; l >= 0 && !collide; l--) { int[] ent = entities.get(l); // If the other entity can collide with the reference entity if (ent[TYPE] < entitytype="" ||="" ent[type]="=" entity_object_type)="" {="" byte[][][]="" model1="models[ent[MODEL]][ent[ANGLE]">> 8]; int sx1 = model1.length; int sy1 = model1[0].length; int sz1 = model1[0][0].length; int x1 = ent[X] >> 8; int y1 = ent[Y] >> 8; int z1 = ent[Z] >> 8; // If it's a collision with the player or a enemy if (cx >= x1 && cx < x1="" +="" sx1="" &&="" cy="">= y1 && cy < y1="" +="" sy1="" &&="" cz="">= z1 && cz < z1="" +="" sz1)="" {="" if="" (ent[type]="">< entity_bullet_type)="" {="" if="" the="" other="" entity="" has="" life="" level="" of="" 1,="" it="" explodes="" if="" (ent[life]="=" 1)="" {="" for="" (i="0;" i="">< sx1;="" i++)="" {="" for="" (j="0;" j="">< sy1;="" j++)="" {="" for="" (k="0;" k="">< sz1;="" k++)="" {="" byte="" block="model1[i][j][k];" if="" (block=""> 0) { addEntity( entities, // TYPE ENTITY_BLOCK_TYPE, // X, Y, Z x1 + i, y1 + j, z1 + k, // DIRX, DIRY, DIRZ entity[DIRX] >> 8, entity[DIRY] >> 8, entity[DIRZ] >> 8, // MODEL, ANGLE, (block & BLOCK_VALUE_BITMASK) + (BLOCK_EPHEMERAL < block_type_shift),="" 0,="" life="" 1,="" forcex,="" forcey,="" forcez="" (i="" -="" (sx1="">> 1)) * 5, (8 + j - (sy1 >> 1)) * 5, (k - (sz1 >> 1)) * 5, // ANIMATION_SPEED 0); } } } } } collide = true; // Apply a external force ent[LIFE]--; ent[FORCEX] = 50 * (ent[X] - entity[X]); ent[FORCEZ] = 50 * (ent[Z] - entity[Z]); } // Collision between player and a object if (entityType == ENTITY_PLAYER_TYPE) { if (ent[MODEL] == MODEL_HEART) { entity[LIFE]++; } if (ent[MODEL] == MODEL_COIN) { nbCoins--; if (nbCoins==0) { gameState = GENERATE_MAP; level++; if (level == 6) { gameState = YOU_WIN; } } } ent[LIFE] = 0; } } } } // Collision between a bullet and the decor if (entityType == ENTITY_BULLET_TYPE && !collide) { for (i = -EXPLOSION_RADIUS; i < explosion_radius;="" i++)="" {="" int="" x1="cx" +="" i="" -="" 1;="" if="" (x1=""> 0) { for (j = -EXPLOSION_RADIUS; j < explosion_radius;="" j++)="" {="" int="" y1="cy" +="" j="" +="" 1;="" if="" (y1=""> 1 && y1 < world_size_y)="" {="" for="" (k="-EXPLOSION_RADIUS;" k="">< explosion_radius;="" k++)="" {="" int="" z1="cz" +="" k="" -="" 1;="" if="" (z1=""> 0) { byte block = box[x1][y1][z1]; if (block > 0 && (block >> BLOCK_TYPE_SHIFT <= block_decor))="" {="" int="" d="(i" *="" i)="" +="" (j="" *="" j)="" +="" (k="" *="" k);="" if="" (d=""></=>< explosion_radius="" *="" explosion_radius="" -="" 1)="" {="" if="" (d=""> 90*EXPLOSION_RADIUS * EXPLOSION_RADIUS / 100) { addEntity( entities, // TYPE ENTITY_BLOCK_TYPE, // X, Y, Z x1, y1, z1, // DIRX, DIRY, DIRZ EXPLOSION_RADIUS_FORCE * i, EXPLOSION_RADIUS_FORCE * j, EXPLOSION_RADIUS_FORCE * k, // MODEL, ANGLE (BLOCK_EPHEMERAL < block_type_shift)="" +="" (block="" &="" block_value_bitmask),="" 0,="" life="" 1,="" forcex,="" forcey,="" forcez="" 0,="" 0,="" 0,="" animation_speed="" 0);="" }="" box[x1][y1][z1]="0;" }="" }="" }="" }="" }="" }="" }="" }="" }="" }="" if="" bullet="" collision="" outside="" the="" voxelbox,="" the="" bullet="" dies="" if="" ((cx="" !="-1" ||="" cz="" !="-1)" &&="" entitytype="=" entity_bullet_type)="" {="" entity[life]="0;" }="" }="" }="" draw="" the="" entity="" into="" the="" voxelbox="" if="" its="" life=""> 0 if (entity[LIFE] > 0) { // Not block entity if (entityType < entity_block_type)="" {="" for="" (i="0;" i="">< sx;="" i++)="" {="" for="" (j="0;" j="">< sy;="" j++)="" {="" for="" (k="0;" k="">< sz;="" k++)="" {="" if="" (box[x="" +="" i][y="" +="" j][z="" +="" k]="=" 0)="" {="" box[x="" +="" i][y="" +="" j][z="" +="" k]="model[i][j][k];" }="" }="" }="" }="" }="" else="" {="" block="" entity="" if="" (entity[touch_ground]="=" 1="" &&="" ((entity[dirx]="" *="" entity[dirx]="" +="" entity[diry]="" *="" entity[diry]="" +="" entity[dirz]="" *="" entity[dirz]="">< min_moving_distance)))="" {="" entity[life]="0;" }="" if="" (box[x][y][z]="">> BLOCK_TYPE_SHIFT == 0) { byte block = (byte) entity[MODEL]; if (entity[LIFE] == 0) block = (byte) ((BLOCK_DECOR < block_type_shift)="" +="" block="" &="" block_value_bitmask);="" box[x][y][z]="block;" }="" }="" launch="" a="" bullet="" in="" the="" direction="" of="" the="" entity="" if="" firing="" is="" true="" if="" (firing="" &&="" now=""> nextBullet) { j = (entity[ANGLE] >> 8) & 3; i = 0; k = 0; if (j == RIGHT_ANGLE) { i = 1; } if (j == LEFT_ANGLE) { i = -1; } if (j == BACK_ANGLE) { k = 1; } if (j == FRONT_ANGLE) { k = -1; } addEntity( entities, // TYPE ENTITY_BULLET_TYPE, // X, Y, Z x + (1 + i) * 4, y + 3, z + (1 + k) * 4, // DIRX, DIRY, DIRZ i * BULLET_SPEED, 0, k * BULLET_SPEED, // MODEL, ANGLE 1, j, // LIFE 1, // FORCEX, FORCEY, FORCEZ 0, 0, 0, // ANIMATION_SPEED 10); nextBullet = now + 320000000; } } // If entity dies if (entity[LIFE] <= 0)="" {="" if="" entity="" is="" a="" enemy="" if="" (entitytype="=" entity_eneny_type)="" {="" randomly="" pop="" a="" heart="" if="" (((int)="" now="" &="" 127)=""> 115) { addEntity( entities, // TYPE ENTITY_OBJECT_TYPE, // X, Y, Z x, y, z, // DIRX, DIRY, DIRZ 0, 0, 0, // MODEL, ANGLE MODEL_HEART, 0, // LIFE 1, // FORCEX, FORCEY, FORCEZ 0, 48, 0, // ANIMATION_SPEED 0); } nbEnemies--; // Increase light strength lightStrength += 2; if (lightStrength >= LIGHT_DISTANCE) lightStrength = LIGHT_DISTANCE-1; } entities.remove(entity); } // Store player attributes if (entityType == ENTITY_PLAYER_TYPE) { playerLife = entity[LIFE]; playerX = x + 5; playerZ = z + 6; } } // Determine frustum position relatively to player frustumX = playerX; frustumZ = playerZ; if (frustumX <= frustum_size)="" {="" frustumx="FRUSTUM_SIZE" +="" 1;="" }="" if="" (frustumx="">= map_size_x - FRUSTUM_SIZE) { frustumX = map_size_x - FRUSTUM_SIZE + 1; } if (frustumZ <= frustum_size)="" {="" frustumz="FRUSTUM_SIZE" +="" 1;="" }="" if="" (frustumz="">= map_size_z - FRUSTUM_SIZE) { frustumZ = map_size_z - FRUSTUM_SIZE + 1; } // Pop enemy if needed if (nbEnemies < nbenemiestopop)="" {="" i="MODEL_BUZZ_ENEMY" +="" ((int)="" now="" &="" 1);="" j="2;" k="20;" if="" (i="=" model_blob_enemy)="" {="" j="1;" k="10;" }="" int="" x="(int)" (math.random()="" *="" mazewidth);="" int="" z="(int)" (math.random()="" *="" mazeheight);="" if="" ((x="" !="(int)" (playerx="" cell_size)="" ||="" z="" !="(int)" (playerz="" cell_size))="" &&="" maze[x][z]="" !="0)" {="" addentity(="" entities,="" type="" entity_eneny_type,="" x,="" y,="" z="" x="" *="" cell_size="" +="" (cell_size="">> 1), 20, z * CELL_SIZE + (CELL_SIZE >> 1), // DIRX, DIRY, DIRZ 0, 0, -1, // MODEL, ANGLE i, 0, // LIFE j, // FORCEX, FORCEY, FORCEZ 0, 0, 0, // ANIMATION_SPEED k); nbEnemies++; } } // Verify if the player looses if (playerLife <= 0="" ||="" lightstrength=""></=><= 14)="" {="" playerlife="0;" gamestate="YOU_LOOSE;" }="" rendering="" by="" column="" for="" (int="" x="(FRUSTUM_SIZE"></=>< 1)="" -="" 1;="" x="">= 0; x--) { // List of blocks for this column ArrayList blocksList = new ArrayList(); // Loop from down to maximum visible blocks (frustumSizeZ + frustumSizeY) for (i = 1; i < world_size_y="" +="" (frustum_size="">< 1);="" i++)="" {="" z="" block="" position="" int="" z="i" -="" world_size_y;="" if="" (z="">< 1)="" {="" z="1;" }="" y="" block="" position="" int="" y="i" -="" z="" -="" 2;="" first="" block="" is="" at="" the="" bottom="" of="" the="" frustum="" (near="" us)="" z="" +="frustumZ" -="" frustum_size;="" loop="" through="" the="" blocks="" on="" the="" same="" view="" ray="" for="" (;="" z="">< frustumz="" +="" frustum_size="" &&="" y=""> 0; z++, y--) { byte block = box[x + frustumX - FRUSTUM_SIZE][y][z]; // Stop when a block is not empty if (block > 0) { // (z < 6)="" -="" y)="" used="" to="" sort="" the="" blocks="" by="" z="" and="" y="" position="" blockslist.add((((z="">< 6)="" -="" y)="">< 12)="" +="" (i="">< 4)="" +="" (block="" &="" block_value_bitmask));="" break;="" }="" }="" }="" sort="" the="" visible="" blocks="" list="" by="" the="" z="" and="" y="" position=""> orderer by Z rendering position Collections.sort(blocksList); // Loop through the visible blocks order by Y rendering position for (j = blocksList.size() - 1; j >= 0; j--) { int value = blocksList.get(j); // block color index int color = (value & BLOCK_VALUE_BITMASK) * LIGHT_DISTANCE; // Initialise distance to max value int z = LIGHT_DISTANCE - 1; // LightSource position in voxelBox int x1 = playerX < 7;="" int="" y1="4096;" 32="">< 7="" int="" z1="playerZ">< 7;="" block="" position="" in="" voxelbox="" int="" x2="x" +="" frustumx="" -="" frustum_size;="" int="" y2="-(value">> 12) & 0x3F; int z2 = (value >> 18); // Ray from lightSource to block int dx = (x2 < 7)="" -="" x1;="" int="" dy="(y2">< 7)="" -="" y1;="" int="" dz="(z2">< 7)="" -="" z1;="" accumulate="" shadow="" produced="" by="" neighbours="" int="" pcf="0;" distance="" between="" lightsource="" and="" block="" int="" len="dx" *="" dx="" +="" dy="" *="" dy="" +="" dz="" *="" dz;="" if="" block="" is="" in="" light="" if="" (len="">< (lightstrength*lightstrength)="">< 14)="" {="" normalise="" ray="" len="((int)" math.sqrt(len)="">> 7) + 1; dx /= len; dy /= len; dz /= len; // Make the start point in the middle of the cell x1 += 64; y1 += 128; // One cell above for artifacts z1 += 64; // Initialise the distance to 0 z = 0; // Loop on the ray till distance over or block hit while (z < len="" -="" 1)="" {="" int="" y3="y1">> 7; if (y3 < world_size_y="" -="" 1)="" {="" int="" x3="x1">> 7; int z3 = z1 >> 7; if (box[x3][y3][z3] != 0) { z = LIGHT_DISTANCE - 1; } // Approximate PCF shadow (not very conventional, but result is not too bad) if (box[x3 - 1][y3][z3] != 0) pcf += PCF_SHADOW; if (box[x3 + 1][y3][z3] != 0) pcf += PCF_SHADOW; if (box[x3][y3][z3 - 1] != 0) pcf += PCF_SHADOW; if (box[x3][y3][z3 + 1] != 0) pcf += PCF_SHADOW; } x1 += dx; y1 += dy; z1 += dz; z++; } // Calculate final lighting z += LIGHT_DISTANCE - lightStrength + pcf; // Approximate ambient occlusion y2++; if (box[x2][y2][z2] == 0) { if (box[x2 - 1][y2][z2] != 0) z += PCF_SHADOW; if (box[x2][y2][z2 - 1] != 0) z += PCF_SHADOW; if (box[x2][y2][z2 + 1] != 0) z += PCF_SHADOW; if (box[x2 + 1][y2][z2] != 0) z += PCF_SHADOW; } // Fit distance in authorised range if (z>=LIGHT_DISTANCE) z = LIGHT_DISTANCE-1; // Calculate front face lighting int fz = (z + LIGHT_DISTANCE) >> 1; // Draw the block l = x * BLOCK_X + (SCREEN_HEIGHT - ((value >> 4) & 0xFF) * BLOCK_Y) * SCREEN_WIDTH; for (i = l + BLOCK_X - 1; i >= l; i--) { pixels[i] = pixels[i + SCREEN_WIDTH] = pixels[i + 2 * SCREEN_WIDTH] = colors[color + z]; pixels[i + 3 * SCREEN_WIDTH] = pixels[i + 4 * SCREEN_WIDTH] = pixels[i + 5 * SCREEN_WIDTH] = colors[color + fz]; } } } } // UI gfx.setColor(Color.green); // Player life gfx.fillRect(10, 10, 14 * playerLife, 10); gfx.setColor(Color.white); // Player light gfx.fillRect(10, 30, lightStrength-14, 10); // Coins left gfx.drawString("Coins x", 606, 20); gfx.drawString(String.valueOf(nbCoins), 650, 20); // Messages and gameState if (DEBUG) { gfx.drawString("FPS : " + String.valueOf(fps), 10, 60); gfx.drawString("Entites : " + String.valueOf(entities.size()), 10, 80); gfx.drawString("Enemies : " + String.valueOf(nbEnemies), 10, 100); } if (gameState > PLAYING) { gfx.clearRect(0, 278, SCREEN_WIDTH, 50); if (gameState != YOU_WIN) { gfx.drawString("ENTER to go", 300, 315); if (keys[KEY_ENTER]) { gameState = PLAYING; if (playerLife <= 0)="" {="" gamestate="GENERATE_MAP;" }="" }="" }="" gfx.setcolor(color.orange);="" if="" (gamestate="=" pause)="" {="" gfx.drawstring("pause",="" 318,="" 296);="" }="" if="" (gamestate="=" you_win)="" {="" gfx.drawstring("congratulations="" !",="" 275,="" 308);="" }="" if="" (gamestate="=" you_loose)="" {="" gfx.drawstring("you="" died",="" 310,="" 296);="" }="" if="" (gamestate="=" next_level)="" {="" gfx.drawstring("level",="" 315,="" 296);="" gfx.drawstring(string.valueof(level),="" 350,="" 296);="" }="" }="" if="" (appletgraphics="=" null)="" appletgraphics="getGraphics();" else="" appletgraphics.drawimage(screen,="" 0,="" 0,="" null);="" }="" }="" @override="" public="" boolean="" handleevent(event="" e)="" {="" return="" keys[e.key]="(e.id" =="Event.KEY_PRESS" ||="" e.id="=" event.key_action);="" }=""></=></=></=></=></8;></=></=></8;></=></=></8;></=></=></8)></8)>