diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9de304c --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +CPP := g++ +INC := src +SRC := src +OBJ := build +LDFLAGS := -L. -lallegro -lallegro_image -lallegro_font -lallegro_ttf -lallegro_dialog -lallegro_video -lallegro_audio -lallegro_physfs -lallegro_primitives -lallegro_acodec -lallegro_main + + +SOURCES := $(wildcard $(SRC)/*.cpp) +OBJECTS := $(patsubst $(SRC)/%.cpp, $(OBJ)/%.o, $(SOURCES)) + +build: env compile + +rebuild: clean build + +env: + mkdir -p build + +$(OBJ)/%.o: $(SRC)/%.cpp + $(CPP) -c -I $(INC) $< -o $@ + +compile: $(OBJECTS) + $(CPP) -o dungeon-looters $^ $(LDFLAGS) + +clean : + rm -rf build dungeon-looters \ No newline at end of file diff --git a/README.md b/README.md index f49ea58..b029846 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,106 @@ -# spjam2012-dungeon-looters -Game was created during the SPjam 2012, a 48hs game development marathon +# Dungeon Looters - SPJAM 2012 + +## Introduction + +The first version of this game was created during the SPjam 2012, a 48hs game +development marathon that took place in Sao Paulo, Brazil, from August 31th to +September 2nd. This is the improved post-marathon version of the game where we +used some 48 additional hours to remove bugs, improve the gameplay, add new +graphics, sounds and music. We hope you like the final version as much as we +liked working on it (and playing it too!). + + +## The Game + +This game is meant to be played by two players that need to cooperate in order +to reach the highest score possible. They must explore a random dungeon killing +monsters, collecting gold and using powerful items. + +At the start of the game, both players receive a random character to control +from a pool of 3 possible classes: Warrior, Mage and Rogue. + +The Warrior has lots of health and has the strongest attack power but he lacks +attack range. The Mage has average health, a ranged attack with average power +but he lacks the speed to keep up with the other two classes. The Rogue is the +fastest class, he can also carry two items but he has a short ranged attack +that lacks the attack power of the other two classes. + +The dungeon is populated by dangerous monsters that will try to hinder the +player's progress. Some of them can be killed by all the three classes but there +are special monsters that can only be killed by specific classes. This is +indicated by the symbols displayed above each monster and above each player. If +the monster has the same symbol as you, you can kill it with your attack. If +the symbols are different, then your attack can't hurt the monster and you'll +need the help of the other player. + +Hidden in the dungeons there are also lots of chests containing items that can +be used by the players. Items cannot be identified until they are collected by a +player. When a player collects a chest, the item contained on it is displayed +at a free item slot owned by that player. + +Players can use theirs items at any time but the effect of the item will always +be provided to the other player. That means you cannot heal yourself with a +health potion if you are one who collected it. + +The game goal is to collect as much gold as possible in 90 seconds. When a +player dies or the time runs out, the game is over. Players can get gold by +collecting gold bags, using items and killing monsters. + + +## Items + +Red Potion - Gives 20 points of health to the other player +Purple Potion - Removes 15 points of health from the other player +Yellow Potion - Gives 20 points of speed to the other player +Green Potion - Removes 15 points of speed from the other player +Blue Potion - Swaps the characters of both players +Amulet - Gives 5 attack power and changes the attack type of the + other player to Mage +Boots - Gives 5 attack power and changes the attack type of the + other player to Rogue +Sword - Gives 5 attack power and changes the attack type of the + other player to Warrior + + +## Controls + +***** Player 1 (Left player) + +Start button - 1 +Movement - W A S D +Attack button - R +Item 1 button - T +Item 2 button - Y + +***** Player 2 (Right player) + +Start button - 2 +Movement - Arrow keys +Attack button - I +Item 1 button - O +Item 2 button - P + +To start the game both players must press start together (1 + 2) + + +# Dev Guide + +## Install in Linux + +sudo apt install allegro5-dev ... + +# Credits + +* Game design and programming by + + Fellipe Augusto Ugliara - + Jeferson Rodrigues da Silva - + +* Graphics by + + Ronaldo Rodrigues da Silva - + +* Music by + + Alex Campos - A3 Studios - + diff --git a/resources/fonts/acttfpc/ATARCC__.TTF b/resources/fonts/acttfpc/ATARCC__.TTF new file mode 100644 index 0000000..4a69e6d Binary files /dev/null and b/resources/fonts/acttfpc/ATARCC__.TTF differ diff --git a/resources/fonts/acttfpc/ATARCE__.TTF b/resources/fonts/acttfpc/ATARCE__.TTF new file mode 100644 index 0000000..8b3c282 Binary files /dev/null and b/resources/fonts/acttfpc/ATARCE__.TTF differ diff --git a/resources/fonts/acttfpc/ATARCS__.TTF b/resources/fonts/acttfpc/ATARCS__.TTF new file mode 100644 index 0000000..ef9bcbb Binary files /dev/null and b/resources/fonts/acttfpc/ATARCS__.TTF differ diff --git a/resources/fonts/acttfpc/ReadMe.rtf b/resources/fonts/acttfpc/ReadMe.rtf new file mode 100644 index 0000000..a36354c --- /dev/null +++ b/resources/fonts/acttfpc/ReadMe.rtf @@ -0,0 +1,317 @@ +{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern\fprq1 Atari Classic Chunky;}{\f3\froman Times New Roman;}{\f4\fswiss\fprq2 Arial;}} +{\colortbl\red0\green0\blue0;\red0\green0\blue255;} +\deflang1033\pard\plain\f2\fs24\cf1 Atari Classic TrueType Fonts \plain\f2\fs24\cf0 +\par \plain\f4\fs16\cf0 (Windows Version 1.1) +\par Created by Mark Simonson (v.1.0-1998, v.1.1-2001) +\par marksim@bitstream.net +\par Website: Mac/Atari Fusion--Atari Home Computer Resources for Mac Users +\par http://www2.bitstream.net/~marksim/atarimac/ +\par Macintosh version also available. +\par +\par With these fonts installed, you can view and print Atari text files in any text editor that allows you to change fonts (WordPad, for example). Tip: In order to get the correct line breaks, you will need to change the ATASCII return character (155) to the DOS LF character. (In the Character Map accessory, the ATASCII return is the blank character that comes just before the inverse up-arrow.) +\par +\par There are three different fonts. \plain\f4\fs16\cf0\b Atari Classic Chunky \plain\f4\fs16\cf0 is a pixel-for-pixel copy of the original ATASCII character set. \plain\f4\fs16\cf0\b Atari Classic Smooth \plain\f4\fs16\cf0 interprets the pixel aliasing (stair steps) as diagonal lines. \plain\f4\fs16\cf0\b Atari Classic Extrasmooth \plain\f4\fs16\cf0 refines this idea further with the addition of curves. \plain\f4\fs16\cf0\b Smooth\plain\f4\fs16\cf0 and \plain\f4\fs16\cf0\b Extrasmooth\plain\f4\fs16\cf0 were designed for better appearance and legibility at larger sizes and on print-outs. Use the one that looks best to you. +\par +\par These fonts will tend to look uneven at font sizes that do not correspond to the 8-by-8 pixel grid that the characters are based on. Because Windows assumes 96ppi screen resolution, they will look best in a font size that is a multiple of 6 (i.e., 6pt, 12pt, 18pt, etc.). (In Windows, 6 points = 8 pixels.) +\par +\par The Atari Classic TrueType fonts duplicate the ATASCII character set on a low-level basis. Unlike a normal Windows font, ATASCII utilizes all character codes from $00 to $FF (0 to 255). The lower half are normal characters; the upper half are inverse versions of the lower half. The basic ASCII characters ($00 to $7F) correspond fairly closely except for the first 32, which don't normally contain characters in a Windows font. +\par +\par Due to differences between the way Windows and the Atari use character codes, not all characters will display properly in Windows. In fact, some characters will not display at all (though they do exist in the font). Unfortunately, this is due to certain character codes being reserved in Windows and there doesn't appear to be any way to work around it. The character codes affected are: $00-$1F (0-31), $7F-$81 (127-129), $8D-$90 (141-144), $9D (157), and $9F (158). +\par +\par Not all characters can be typed from the keyboard. You can however copy characters as needed from this document (see tables below). The Character Map desk accessory can help also. +\par +\par \plain\f4\fs16\cf0\b ATASCII CHARACTER SET TABLES +\par \plain\f4\fs16\cf0 +\par In order to see the ATASCII character set with these tables, the Atari Classic TrueType fonts must be installed. Characters that are not displayed properly are due to character code usage differences between ATASCII and Windows (see above). +\par +\par +\par \plain\f4\fs16\cf0\b TABLE 1: ATASCII Character Dump Block +\par \plain\f4\fs16\cf0 +\par All characters (ATASCII $00 thru $FF) 16 characters per +\par line. +\par +\par +\par \plain\f2\fs12\cf0 \'01\'02\'03\'04\'05\'06\'07\'08\tab +\par \'0b\'0c +\par \'0e\'0f +\par \'10\'11\'12\'13\'14\'15\'16\'17\'18\'19\'1a\'1b\'1c\'1d\'1e\'1f +\par !"#$%&'()*+,-./ +\par 0123456789:;<=>? +\par @ABCDEFGHIJKLMNO +\par PQRSTUVWXYZ[\\]^_ +\par `abcdefghijklmno +\par pqrstuvwxyz\{|\}~ +\par \'80\'81\'82\'83\'84\'85\'86\'87\'88\'89\'8a\'8b\'8c\'8d\'8e\'8f +\par \'90''""\bullet \endash \emdash \'98\'99\'9a \'9c\'9d\'9e\'9f +\par \~\'a1\'a2\'a3\'a4\'a5\'a6\'a7\'a8\'a9\'aa\'ab\'ac\'ad\'ae\'af +\par \'b0\'b1\'b2\'b3\'b4\'b5\'b6\'b7\'b8\'b9\'ba\'bb\'bc\'bd\'be\'bf +\par \'c0\'c1\'c2\'c3\'c4\'c5\'c6\'c7\'c8\'c9\'ca\'cb\'cc\'cd\'ce\'cf +\par \'d0\'d1\'d2\'d3\'d4\'d5\'d6\'d7\'d8\'d9\'da\'db\'dc\'dd\'de\'df +\par \'e0\'e1\'e2\'e3\'e4\'e5\'e6\'e7\'e8\'e9\'ea\'eb\'ec\'ed\'ee\'ef +\par \'f0\'f1\'f2\'f3\'f4\'f5\'f6\'f7\'f8\'f9\'fa\'fb\'fc\'fd\'fe\'ff +\par \plain\f4\fs16\cf0 +\par +\par \plain\f4\fs16\cf0\b TABLE 2: ATASCII Character Dump List +\par \plain\f4\fs16\cf0 +\par All characters (ATASCII $00 thru $FF) one character per +\par line with hexadecimal value indicated on the left. +\par +\par \plain\f2\fs12\cf0 00= +\par 01=\'01 +\par 02=\'02 +\par 03=\'03 +\par 04=\'04 +\par 05=\'05 +\par 06=\'06 +\par 07=\'07 +\par 08=\'08 +\par 09=\tab +\par 0A= +\par +\par 0B=\'0b +\par 0C=\'0c +\par 0D= +\par 0E=\'0e +\par 0F=\'0f +\par 10=\'10 +\par 11=\'11 +\par 12=\'12 +\par 13=\'13 +\par 14=\'14 +\par 15=\'15 +\par 16=\'16 +\par 17=\'17 +\par 18=\'18 +\par 19=\'19 +\par 1A=\'1a +\par 1B=\'1b +\par 1C=\'1c +\par 1D=\'1d +\par 1E=\'1e +\par 1F=\'1f +\par 20= +\par 21=! +\par 22=" +\par 23=# +\par 24=$ +\par 25=% +\par 26=& +\par 27=' +\par 28=( +\par 29=) +\par 2A=* +\par 2B=+ +\par 2C=, +\par 2D=- +\par 2E=. +\par 2F=/ +\par 30=0 +\par 31=1 +\par 32=2 +\par 33=3 +\par 34=4 +\par 35=5 +\par 36=6 +\par 37=7 +\par 38=8 +\par 39=9 +\par 3A=: +\par 3B=; +\par 3C=< +\par 3D== +\par 3E=> +\par 3F=? +\par 40=@ +\par 41=A +\par 42=B +\par 43=C +\par 44=D +\par 45=E +\par 46=F +\par 47=G +\par 48=H +\par 49=I +\par 4A=J +\par 4B=K +\par 4C=L +\par 4D=M +\par 4E=N +\par 4F=O +\par 50=P +\par 51=Q +\par 52=R +\par 53=S +\par 54=T +\par 55=U +\par 56=V +\par 57=W +\par 58=X +\par 59=Y +\par 5A=Z +\par 5B=[ +\par 5C=\\ +\par 5D=] +\par 5E=^ +\par 5F=_ +\par 60=` +\par 61=a +\par 62=b +\par 63=c +\par 64=d +\par 65=e +\par 66=f +\par 67=g +\par 68=h +\par 69=i +\par 6A=j +\par 6B=k +\par 6C=l +\par 6D=m +\par 6E=n +\par 6F=o +\par 70=p +\par 71=q +\par 72=r +\par 73=s +\par 74=t +\par 75=u +\par 76=v +\par 77=w +\par 78=x +\par 79=y +\par 7A=z +\par 7B=\{ +\par 7C=| +\par 7D=\} +\par 7E=~ +\par 7F= +\par 80=\'80 +\par 81=\'81 +\par 82=\'82 +\par 83=\'83 +\par 84=\'84 +\par 85=\'85 +\par 86=\'86 +\par 87=\'87 +\par 88=\'88 +\par 89=\'89 +\par 8A=\'8a +\par 8B=\'8b +\par 8C=\'8c +\par 8D=\'8d +\par 8E=\'8e +\par 8F=\'8f +\par 90=\'90 +\par 91=' +\par 92=' +\par 93=" +\par 94=" +\par 95=\bullet +\par 96=\endash +\par 97=\emdash +\par 98=\'98 +\par 99=\'99 +\par 9A=\'9a +\par 9B= +\par 9C=\'9c +\par 9D=\'9d +\par 9E=\'9e +\par 9F=\'9f +\par A0=\~ +\par A1=\'a1 +\par A2=\'a2 +\par A3=\'a3 +\par A4=\'a4 +\par A5=\'a5 +\par A6=\'a6 +\par A7=\'a7 +\par A8=\'a8 +\par A9=\'a9 +\par AA=\'aa +\par AB=\'ab +\par AC=\'ac +\par AD=\'ad +\par AE=\'ae +\par AF=\'af +\par B0=\'b0 +\par B1=\'b1 +\par B2=\'b2 +\par B3=\'b3 +\par B4=\'b4 +\par B5=\'b5 +\par B6=\'b6 +\par B7=\'b7 +\par B8=\'b8 +\par B9=\'b9 +\par BA=\'ba +\par BB=\'bb +\par BC=\'bc +\par BD=\'bd +\par BE=\'be +\par BF=\'bf +\par C0=\'c0 +\par C1=\'c1 +\par C2=\'c2 +\par C3=\'c3 +\par C4=\'c4 +\par C5=\'c5 +\par C6=\'c6 +\par C7=\'c7 +\par C8=\'c8 +\par C9=\'c9 +\par CA=\'ca +\par CB=\'cb +\par CC=\'cc +\par CD=\'cd +\par CE=\'ce +\par CF=\'cf +\par D0=\'d0 +\par D1=\'d1 +\par D2=\'d2 +\par D3=\'d3 +\par D4=\'d4 +\par D5=\'d5 +\par D6=\'d6 +\par D7=\'d7 +\par D8=\'d8 +\par D9=\'d9 +\par DA=\'da +\par DB=\'db +\par DC=\'dc +\par DD=\'dd +\par DE=\'de +\par DF=\'df +\par E0=\'e0 +\par E1=\'e1 +\par E2=\'e2 +\par E3=\'e3 +\par E4=\'e4 +\par E5=\'e5 +\par E6=\'e6 +\par E7=\'e7 +\par E8=\'e8 +\par E9=\'e9 +\par EA=\'ea +\par EB=\'eb +\par EC=\'ec +\par ED=\'ed +\par EE=\'ee +\par EF=\'ef +\par F0=\'f0 +\par F1=\'f1 +\par F2=\'f2 +\par F3=\'f3 +\par F4=\'f4 +\par F5=\'f5 +\par F6=\'f6 +\par F7=\'f7 +\par F8=\'f8 +\par F9=\'f9 +\par FA=\'fa +\par FB=\'fb +\par FC=\'fc +\par FD=\'fd +\par FE=\'fe +\par FF=\'ff +\par } + \ No newline at end of file diff --git a/resources/fonts/segoepr.ttf b/resources/fonts/segoepr.ttf new file mode 100644 index 0000000..38f696d Binary files /dev/null and b/resources/fonts/segoepr.ttf differ diff --git a/resources/fonts/segoeprb.ttf b/resources/fonts/segoeprb.ttf new file mode 100644 index 0000000..c7e267e Binary files /dev/null and b/resources/fonts/segoeprb.ttf differ diff --git a/resources/graphics/amulet.png b/resources/graphics/amulet.png new file mode 100644 index 0000000..65e354a Binary files /dev/null and b/resources/graphics/amulet.png differ diff --git a/resources/graphics/bat.png b/resources/graphics/bat.png new file mode 100644 index 0000000..9a9cba8 Binary files /dev/null and b/resources/graphics/bat.png differ diff --git a/resources/graphics/boot.png b/resources/graphics/boot.png new file mode 100644 index 0000000..d2984a3 Binary files /dev/null and b/resources/graphics/boot.png differ diff --git a/resources/graphics/construct.png b/resources/graphics/construct.png new file mode 100644 index 0000000..da88d78 Binary files /dev/null and b/resources/graphics/construct.png differ diff --git a/resources/graphics/credits.png b/resources/graphics/credits.png new file mode 100644 index 0000000..fb96ca6 Binary files /dev/null and b/resources/graphics/credits.png differ diff --git a/resources/graphics/darkness.png b/resources/graphics/darkness.png new file mode 100644 index 0000000..4bd1e7c Binary files /dev/null and b/resources/graphics/darkness.png differ diff --git a/resources/graphics/gameover.png b/resources/graphics/gameover.png new file mode 100644 index 0000000..fc0436f Binary files /dev/null and b/resources/graphics/gameover.png differ diff --git a/resources/graphics/ghost.png b/resources/graphics/ghost.png new file mode 100644 index 0000000..c7f10ce Binary files /dev/null and b/resources/graphics/ghost.png differ diff --git a/resources/graphics/goblin.png b/resources/graphics/goblin.png new file mode 100644 index 0000000..dad2ef0 Binary files /dev/null and b/resources/graphics/goblin.png differ diff --git a/resources/graphics/gold.png b/resources/graphics/gold.png new file mode 100644 index 0000000..2efec81 Binary files /dev/null and b/resources/graphics/gold.png differ diff --git a/resources/graphics/helmet.png b/resources/graphics/helmet.png new file mode 100644 index 0000000..974c3e2 Binary files /dev/null and b/resources/graphics/helmet.png differ diff --git a/resources/graphics/instructions.png b/resources/graphics/instructions.png new file mode 100644 index 0000000..825f170 Binary files /dev/null and b/resources/graphics/instructions.png differ diff --git a/resources/graphics/items.png b/resources/graphics/items.png new file mode 100644 index 0000000..a5fc98f Binary files /dev/null and b/resources/graphics/items.png differ diff --git a/resources/graphics/loot.png b/resources/graphics/loot.png new file mode 100644 index 0000000..e8fa62e Binary files /dev/null and b/resources/graphics/loot.png differ diff --git a/resources/graphics/mage.png b/resources/graphics/mage.png new file mode 100644 index 0000000..0033107 Binary files /dev/null and b/resources/graphics/mage.png differ diff --git a/resources/graphics/medusa.png b/resources/graphics/medusa.png new file mode 100644 index 0000000..3453ab7 Binary files /dev/null and b/resources/graphics/medusa.png differ diff --git a/resources/graphics/minotaur.png b/resources/graphics/minotaur.png new file mode 100644 index 0000000..33471b4 Binary files /dev/null and b/resources/graphics/minotaur.png differ diff --git a/resources/graphics/particles.png b/resources/graphics/particles.png new file mode 100644 index 0000000..c056460 Binary files /dev/null and b/resources/graphics/particles.png differ diff --git a/resources/graphics/playerhud.png b/resources/graphics/playerhud.png new file mode 100644 index 0000000..0a4f719 Binary files /dev/null and b/resources/graphics/playerhud.png differ diff --git a/resources/graphics/potion_haste.png b/resources/graphics/potion_haste.png new file mode 100644 index 0000000..bfc3f97 Binary files /dev/null and b/resources/graphics/potion_haste.png differ diff --git a/resources/graphics/potion_life.png b/resources/graphics/potion_life.png new file mode 100644 index 0000000..d5fc6f2 Binary files /dev/null and b/resources/graphics/potion_life.png differ diff --git a/resources/graphics/potion_poison.png b/resources/graphics/potion_poison.png new file mode 100644 index 0000000..ede2acd Binary files /dev/null and b/resources/graphics/potion_poison.png differ diff --git a/resources/graphics/potion_slow.png b/resources/graphics/potion_slow.png new file mode 100644 index 0000000..af93cbe Binary files /dev/null and b/resources/graphics/potion_slow.png differ diff --git a/resources/graphics/rogue.png b/resources/graphics/rogue.png new file mode 100644 index 0000000..bfb55b1 Binary files /dev/null and b/resources/graphics/rogue.png differ diff --git a/resources/graphics/spider.png b/resources/graphics/spider.png new file mode 100644 index 0000000..cb4e115 Binary files /dev/null and b/resources/graphics/spider.png differ diff --git a/resources/graphics/swap.png b/resources/graphics/swap.png new file mode 100644 index 0000000..16a3dba Binary files /dev/null and b/resources/graphics/swap.png differ diff --git a/resources/graphics/tileset.png b/resources/graphics/tileset.png new file mode 100644 index 0000000..f738452 Binary files /dev/null and b/resources/graphics/tileset.png differ diff --git a/resources/graphics/title.png b/resources/graphics/title.png new file mode 100644 index 0000000..17049cc Binary files /dev/null and b/resources/graphics/title.png differ diff --git a/resources/graphics/warrior.png b/resources/graphics/warrior.png new file mode 100644 index 0000000..4bff7ae Binary files /dev/null and b/resources/graphics/warrior.png differ diff --git a/resources/graphics/weakness.png b/resources/graphics/weakness.png new file mode 100644 index 0000000..c57b606 Binary files /dev/null and b/resources/graphics/weakness.png differ diff --git a/resources/graphics/witch.png b/resources/graphics/witch.png new file mode 100644 index 0000000..779b61c Binary files /dev/null and b/resources/graphics/witch.png differ diff --git a/resources/graphics/zombie.png b/resources/graphics/zombie.png new file mode 100644 index 0000000..4829f57 Binary files /dev/null and b/resources/graphics/zombie.png differ diff --git a/resources/music/Deep Buried Treasure.ogg b/resources/music/Deep Buried Treasure.ogg new file mode 100644 index 0000000..34fdd73 Binary files /dev/null and b/resources/music/Deep Buried Treasure.ogg differ diff --git a/resources/music/music.ogg b/resources/music/music.ogg new file mode 100644 index 0000000..be02574 Binary files /dev/null and b/resources/music/music.ogg differ diff --git a/resources/sound/bat.wav b/resources/sound/bat.wav new file mode 100644 index 0000000..5f06243 Binary files /dev/null and b/resources/sound/bat.wav differ diff --git a/resources/sound/classchange.wav b/resources/sound/classchange.wav new file mode 100644 index 0000000..bee7786 Binary files /dev/null and b/resources/sound/classchange.wav differ diff --git a/resources/sound/clock.wav b/resources/sound/clock.wav new file mode 100644 index 0000000..1cdeda1 Binary files /dev/null and b/resources/sound/clock.wav differ diff --git a/resources/sound/construct.wav b/resources/sound/construct.wav new file mode 100644 index 0000000..cb7884e Binary files /dev/null and b/resources/sound/construct.wav differ diff --git a/resources/sound/dagger.wav b/resources/sound/dagger.wav new file mode 100644 index 0000000..c309657 Binary files /dev/null and b/resources/sound/dagger.wav differ diff --git a/resources/sound/death.wav b/resources/sound/death.wav new file mode 100644 index 0000000..3664c15 Binary files /dev/null and b/resources/sound/death.wav differ diff --git a/resources/sound/fireball.wav b/resources/sound/fireball.wav new file mode 100644 index 0000000..1a1880f Binary files /dev/null and b/resources/sound/fireball.wav differ diff --git a/resources/sound/ghost.wav b/resources/sound/ghost.wav new file mode 100644 index 0000000..a9ecc58 Binary files /dev/null and b/resources/sound/ghost.wav differ diff --git a/resources/sound/goblin.wav b/resources/sound/goblin.wav new file mode 100644 index 0000000..e39705d Binary files /dev/null and b/resources/sound/goblin.wav differ diff --git a/resources/sound/gold.wav b/resources/sound/gold.wav new file mode 100644 index 0000000..7351bcf Binary files /dev/null and b/resources/sound/gold.wav differ diff --git a/resources/sound/haste.wav b/resources/sound/haste.wav new file mode 100644 index 0000000..0fa8ffa Binary files /dev/null and b/resources/sound/haste.wav differ diff --git a/resources/sound/heal.wav b/resources/sound/heal.wav new file mode 100644 index 0000000..3c42703 Binary files /dev/null and b/resources/sound/heal.wav differ diff --git a/resources/sound/hurt.wav b/resources/sound/hurt.wav new file mode 100644 index 0000000..143b0d0 Binary files /dev/null and b/resources/sound/hurt.wav differ diff --git a/resources/sound/loot.wav b/resources/sound/loot.wav new file mode 100644 index 0000000..6804fe7 Binary files /dev/null and b/resources/sound/loot.wav differ diff --git a/resources/sound/medusa.wav b/resources/sound/medusa.wav new file mode 100644 index 0000000..2b9697c Binary files /dev/null and b/resources/sound/medusa.wav differ diff --git a/resources/sound/minotaur.wav b/resources/sound/minotaur.wav new file mode 100644 index 0000000..8859a1a Binary files /dev/null and b/resources/sound/minotaur.wav differ diff --git a/resources/sound/miss.wav b/resources/sound/miss.wav new file mode 100644 index 0000000..847421c Binary files /dev/null and b/resources/sound/miss.wav differ diff --git a/resources/sound/poison.wav b/resources/sound/poison.wav new file mode 100644 index 0000000..7c4c60e Binary files /dev/null and b/resources/sound/poison.wav differ diff --git a/resources/sound/slow.wav b/resources/sound/slow.wav new file mode 100644 index 0000000..ee3b7bb Binary files /dev/null and b/resources/sound/slow.wav differ diff --git a/resources/sound/spider.wav b/resources/sound/spider.wav new file mode 100644 index 0000000..c844477 Binary files /dev/null and b/resources/sound/spider.wav differ diff --git a/resources/sound/swap.wav b/resources/sound/swap.wav new file mode 100644 index 0000000..b56ef50 Binary files /dev/null and b/resources/sound/swap.wav differ diff --git a/resources/sound/sword.wav b/resources/sound/sword.wav new file mode 100644 index 0000000..99f954c Binary files /dev/null and b/resources/sound/sword.wav differ diff --git a/resources/sound/title_stop.wav b/resources/sound/title_stop.wav new file mode 100644 index 0000000..3279efe Binary files /dev/null and b/resources/sound/title_stop.wav differ diff --git a/resources/sound/witch.wav b/resources/sound/witch.wav new file mode 100644 index 0000000..18e037d Binary files /dev/null and b/resources/sound/witch.wav differ diff --git a/resources/sound/zombie.wav b/resources/sound/zombie.wav new file mode 100644 index 0000000..56f6a4b Binary files /dev/null and b/resources/sound/zombie.wav differ diff --git a/src/amulet.cpp b/src/amulet.cpp new file mode 100644 index 0000000..aa8e37c --- /dev/null +++ b/src/amulet.cpp @@ -0,0 +1,69 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "amulet.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *Amulet::sound = 0; + +Amulet::Amulet():Item(AMULET) { +} + +Amulet::~Amulet() { +} + +void Amulet::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void Amulet::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player *use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + + use->playerType = MAGE; + target = use; +} + +ParticleSystem *Amulet::getUseParticles() { + Particle *particle = new Particle(11, 32, 32, 0.03, 1.0, 0.0, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_IN, target, 120, 0, 0.3); + + return particleSystem; +} + +void Amulet::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/classchange.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/amulet.h b/src/amulet.h new file mode 100644 index 0000000..af9f9cd --- /dev/null +++ b/src/amulet.h @@ -0,0 +1,40 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef AMULET_H +#define AMULET_H + +#include "item.h" +#include +#include + +class Amulet : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + Amulet(); + ~Amulet(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + + +#endif // AMULET_H diff --git a/src/bat.cpp b/src/bat.cpp new file mode 100644 index 0000000..3740e89 --- /dev/null +++ b/src/bat.cpp @@ -0,0 +1,130 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "bat.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Bat::bat = 0; +ALLEGRO_SAMPLE *Bat::sound = 0; + +Bat::Bat() { + life = 10; + power = 5; + speed = 330; + maxSpeed = speed; + weakness = ALL; + width = 48; + height = 48; + gold = 1; +} + +Bat::~Bat() { +} + +void Bat::render(double edt) { + if (!bat) { + bat = al_load_bitmap("resources/graphics/bat.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(bat, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(bat, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Bat::getDeathParticles() { + Particle *particle = new Particle(5, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Bat:: +artificialIntelligence(double dt, Map *map, std::vector entities) { + if(inercia <= 0) { + int interval = 1 - 0 + 1;//MAX-MIN+1 + int numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + state = MOVE; + inercia = 1.0; + if(state == MOVE) { + inercia = 1.0; + interval = 7 - 0 + 1;//MAX-MIN+1 + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDx = dxMoster[numRand]; + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDy = dyMoster[numRand]; + if (stepDx > 0) { + flags = ALLEGRO_FLIP_HORIZONTAL; + } + } + } + + Vector2D curPos; + Vector2D move; + BoundingBox box ; + switch(state) { + case MOVE: + curPos = position; + move = Vector2D(stepDx,stepDy); + move = move.mult(speed * dt); + position = position.add(Vector2D(move.getX(), 0)); + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0) { + if (move.getX() > 0) { + int dx = (position.getX() + width / 2) - box.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, move.getY())); + box = hasMapCollision(map); + if (box.getMaxY() - box.getMinY() > 0) { + if (move.getY() > 0) { + int dy = (position.getY() + height / 2) - box.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + inercia-=dt; + break; + } +} + +void Bat::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/bat.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/bat.h b/src/bat.h new file mode 100644 index 0000000..be0bf77 --- /dev/null +++ b/src/bat.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef BAT_H +#define BAT_H + +#include "monster.h" +#include +#include + +class Bat : public Monster { +public: + static ALLEGRO_BITMAP *bat; + static ALLEGRO_SAMPLE *sound; + + Bat(); + ~Bat(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void artificialIntelligence(double dt, Map *map, std::vector entities); + void playSound(); +}; + +#endif // BAT_H diff --git a/src/boots.cpp b/src/boots.cpp new file mode 100644 index 0000000..e597de4 --- /dev/null +++ b/src/boots.cpp @@ -0,0 +1,69 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "boots.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *Boots::sound = 0; + +Boots::Boots():Item(BOOTS_OF_SPEED) { +} + +Boots::~Boots() { +} + +void Boots::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void Boots::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player *use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + + use->playerType = ROGUE; + target = use; +} + +ParticleSystem *Boots::getUseParticles() { + Particle *particle = new Particle(12, 32, 32, 0.03, 1.0, 0.0, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_IN, target, 120, 0, 0.3); + + return particleSystem; +} + +void Boots::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/classchange.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/boots.h b/src/boots.h new file mode 100644 index 0000000..9f41aec --- /dev/null +++ b/src/boots.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef BOOTS_H +#define BOOTS_H + +#include "item.h" +#include +#include + +class Boots : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + Boots(); + ~Boots(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // BOOTS_H diff --git a/src/bounding-box.cpp b/src/bounding-box.cpp new file mode 100644 index 0000000..fd58f85 --- /dev/null +++ b/src/bounding-box.cpp @@ -0,0 +1,70 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "bounding-box.h" +#include + +BoundingBox::BoundingBox() { + +} + +BoundingBox::BoundingBox(Vector2D a, Vector2D b) { + upperLeft.setX(std::min(a.getX(), b.getX())); + upperLeft.setY(std::min(a.getY(), b.getY())); + lowerRight.setX(std::max(a.getX(), b.getX())); + lowerRight.setY(std::max(a.getY(), b.getY())); +} + +BoundingBox::BoundingBox(int x, int y, int width, int height) { + upperLeft.setX(x); + upperLeft.setY(y); + lowerRight.setX(x + width); + lowerRight.setY(y + height); +} + +BoundingBox::~BoundingBox() { + +} + +double BoundingBox::getMinX() { + return upperLeft.getX(); +} + +double BoundingBox::getMaxX() { + return lowerRight.getX(); +} + +double BoundingBox::getMinY() { + return upperLeft.getY(); +} + +double BoundingBox::getMaxY() { + return lowerRight.getY(); +} + +bool BoundingBox::intersects(BoundingBox box) { + bool intersects = true; + + if (getMaxX() <= box.getMinX() || + getMinX() >= box.getMaxX() || + getMaxY() <= box.getMinY() || + getMinY() >= box.getMaxY()) { + intersects = false; + } + + return intersects; +} diff --git a/src/bounding-box.h b/src/bounding-box.h new file mode 100644 index 0000000..936d94d --- /dev/null +++ b/src/bounding-box.h @@ -0,0 +1,41 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _BOUNDING_BOX_H +#define _BOUNDING_BOX_H + +#include "vector2d.h" + +class BoundingBox { + private: + Vector2D upperLeft; + Vector2D lowerRight; + + public: + BoundingBox(); + BoundingBox(Vector2D a, Vector2D b); + BoundingBox(int x, int y, int width, int height); + ~BoundingBox(); + + double getMinX(); + double getMaxX(); + double getMinY(); + double getMaxY(); + bool intersects(BoundingBox box); +}; + +#endif diff --git a/src/construct.cpp b/src/construct.cpp new file mode 100644 index 0000000..7099d89 --- /dev/null +++ b/src/construct.cpp @@ -0,0 +1,75 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "construct.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Construct::construct = 0; +ALLEGRO_SAMPLE *Construct::sound = 0; + +Construct::Construct() { + life = 160; + power = 30; + speed = 192; + maxSpeed = speed; + weakness = WARRIOR; + width = 48; + height = 48; + gold = 3; +} + +Construct::~Construct() { +} + +void Construct::render(double edt) { + if (!construct) { + construct = al_load_bitmap("resources/graphics/construct.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(construct, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(construct, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Construct::getDeathParticles() { + Particle *particle = new Particle(4, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Construct::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/construct.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + diff --git a/src/construct.h b/src/construct.h new file mode 100644 index 0000000..0e9f260 --- /dev/null +++ b/src/construct.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef CONSTRUCT_H +#define CONSTRUCT_H + +#include "monster.h" +#include +#include + +class Construct : public Monster { +public: + static ALLEGRO_BITMAP *construct; + static ALLEGRO_SAMPLE *sound; + + Construct(); + ~Construct(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // CONSTRUCT_H diff --git a/src/dagger.cpp b/src/dagger.cpp new file mode 100644 index 0000000..3c09554 --- /dev/null +++ b/src/dagger.cpp @@ -0,0 +1,186 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "dagger.h" +#include "rogue.h" +#include "window.h" +#include "monster.h" + +Dagger::Dagger(Player *player, Orientation orientation, int damage) { + type = PROJECTILE; + this->player = player; + this->orientation = orientation; + this->position = player->position; + this->damage = damage; + this->range = 100.0; + + width = 48; + height = 48; + + switch (orientation) { + case FACING_UP: + vel = Vector2D(0, -1); + position = position.add(Vector2D(0, -height)); + break; + case FACING_RIGHT: + vel = Vector2D(1, 0); + position = position.add(Vector2D(width, 0)); + break; + case FACING_DOWN: + vel = Vector2D(0, 1); + position = position.add(Vector2D(0, height)); + break; + case FACING_LEFT: + vel = Vector2D(-1, 0); + position = position.add(Vector2D(-width, 0)); + break; + } + + speed = 512.0; + dead = false; +} + +Dagger::~Dagger() { + +} + +void Dagger::collisionWith(Entity *entity) { + if (entity->type == MONSTER) { + Monster *monster = (Monster *)entity; + monster->slowDuration = 1.0; + if (monster->weakness == ALL || monster->weakness == player->playerType) { + if (monster->immunity <= 0.0) { + monster->playSound(); + monster->life -= damage; + if (monster->life < 0.0) { + monster->life = 0.0; + player->gold += monster->gold; + } + monster->immunity = 0.5; + } + } else { + player->playMissSound(); + } + } +} + +void Dagger::update(double dt, Map *map, std::vector entities) { + position = position.add(vel.mult(speed * dt)); + range -= speed * dt; + if (range <= 0.0) { + dead = true; + return; + } + + Entity *result = 0; + BoundingBox box = BoundingBox(position.getX() - width / 4, + position.getY() - height / 4, + width / 2, height / 2); + + // colisão com entidades + if (!result) { + for (unsigned int i = 0; i < entities.size(); i++) { + if (entities[i]->type == MONSTER) { + BoundingBox entityBox = BoundingBox(entities[i]->position.getX() - entities[i]->width / 2, + entities[i]->position.getY() - entities[i]->height / 2, + entities[i]->width, entities[i]->height); + if (box.intersects(entityBox)) { + result = entities[i]; + dead = true; + break; + } + } + } + } + + if (result) { + collisionWith(result); + } else { + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0 || + box.getMaxY() - box.getMinY()) { + dead = true; + } + } +} + +BoundingBox Dagger::hasMapCollision(Map *map) { + BoundingBox result = BoundingBox(0, 0, 0, 0); + BoundingBox box = BoundingBox(position.getX() - width / 6, + position.getY() - height / 6, + width / 3, height / 3); + + int tileX = position.getX() / TILESET_WIDTH; + int tileY = position.getY() / TILESET_HEIGHT; + + // colisão com o mapa + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int x = tileX + dx; + int y = tileY + dy; + if (map->tiles[y][x] == WALL) { + BoundingBox tileBox = BoundingBox(x * TILESET_WIDTH, y * TILESET_HEIGHT, + TILESET_WIDTH, TILESET_HEIGHT); + if (box.intersects(tileBox)) { + result = tileBox; + return result; + } + } + } + } + + return result; +} + +void Dagger::render(double edt) { + if (!Rogue::rogue) { + Rogue::rogue = al_load_bitmap("resources/graphics/rogue.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + switch (orientation) { + case FACING_UP: + al_draw_tinted_scaled_rotated_bitmap_region(Rogue::rogue, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 0.0, 0); + break; + + case FACING_RIGHT: + al_draw_tinted_scaled_rotated_bitmap_region(Rogue::rogue, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.14 / 2.0, 0); + break; + + case FACING_DOWN: + al_draw_tinted_scaled_rotated_bitmap_region(Rogue::rogue, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.14, 0); + break; + + case FACING_LEFT: + al_draw_tinted_scaled_rotated_bitmap_region(Rogue::rogue, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.0 * 3.14 / 2.0, 0); + break; + } +} + +bool Dagger::isDead() { + return dead; +} diff --git a/src/dagger.h b/src/dagger.h new file mode 100644 index 0000000..a66dbab --- /dev/null +++ b/src/dagger.h @@ -0,0 +1,46 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef DAGGER_H +#define DAGGER_H + +#include "entity.h" +#include "player.h" + +class Dagger : public Entity { +public: + Dagger(Player *player, Orientation orientation, int damage); + ~Dagger(); + + Player *player; + Orientation orientation; + double attackTime; + int damage; + double range; + + Vector2D vel; + double speed; + bool dead; + + void collisionWith(Entity *entity); + BoundingBox hasMapCollision(Map *map); + void update(double dt, Map *map, std::vector entities); + void render(double edt); + bool isDead(); +}; + +#endif // DAGGER_H diff --git a/src/engine.cpp b/src/engine.cpp new file mode 100644 index 0000000..c7fea1d --- /dev/null +++ b/src/engine.cpp @@ -0,0 +1,213 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "engine.h" +#include "game.h" +#include "window.h" + +Game::Engine::Engine() { + + if(!al_init()) { + fprintf(stderr, "failed to initialize allegro!\n"); + } + + if (!al_install_audio()) { + fprintf(stderr, "failed to initialize the audio!\n"); + } + + if (!al_init_acodec_addon()) { + fprintf(stderr, "failed to initialize the audio codec addon!\n"); + } + + if (!al_reserve_samples(16)) { + fprintf(stderr, "failed to reserve samples for audio!\n"); + } + + if(!al_install_mouse()) { + fprintf(stderr, "failed to initialize the mouse!\n"); + } + + if(!al_install_keyboard()) { + fprintf(stderr, "failed to initialize the keyboard!\n"); + } + + if(!al_init_image_addon()) { + fprintf(stderr, "Failed to initialize al_init_image_addon!\n"); + } + + if(!al_init_primitives_addon()) { + fprintf(stderr, "Failed to initialize al_init_primitives_addon!\n"); + } + + al_init_font_addon(); + if(!al_init_ttf_addon()) { + fprintf(stderr, "Failed to initialize al_init_primitives_addon!\n"); + } + + music = al_load_sample( "resources/music/music.ogg" ); + if (!music) { + printf( "Audio clip sample not loaded!\n" ); + } + // timerUpdate = al_create_timer(1.0 / this->UPS); + //if(!timerUpdate) { + // fprintf(stderr, "failed to create timerUpdate!\n"); + //} + + this->event_queue = al_create_event_queue(); + if(!this->event_queue) { + fprintf(stderr, "failed to create event_queue!\n"); + al_destroy_display(this->display); + al_destroy_timer(timerUpdate); + } + +// al_register_event_source(this->event_queue, al_get_timer_event_source(this->timerUpdate)); + al_register_event_source(this->event_queue, al_get_mouse_event_source()); + al_register_event_source(this->event_queue, al_get_keyboard_event_source()); + +// this->mutex = al_create_mutex(); + + this->currentScreen = 0; + this->endGame = false; + this->gold = 0; + + al_set_new_bitmap_flags( ALLEGRO_NO_PREMULTIPLIED_ALPHA ); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); +} + +Game::Engine::~Engine() { + al_uninstall_audio(); + + al_destroy_thread(this->thread_update); + + al_destroy_timer(this->timerUpdate); + al_destroy_display(this->display); + al_destroy_event_queue(this->event_queue); +} + +void Game::Engine::run() { + draw_old_time = al_get_time(); + + Window *window = Window::getInstance(); + window->setSize(1280, 720); + display = al_create_display(window->getWidth(), window->getHeight()); + if(!display) { + fprintf(stderr, "failed to create display!\n"); + al_destroy_timer(timerUpdate); + } + + al_register_event_source(event_queue, al_get_display_event_source(display)); + + screen[currentScreen]->start(this); + + loop(); + +// this->thread_update = al_create_thread(Game::Engine::updateThread, this); +// al_start_thread(thread_update); + +// while(!this->endGame) { +// double current_time = al_get_time(); +// delta_time = current_time - draw_old_time; +// if (update_old_time < draw_old_time) { +// delta_time = current_time - update_old_time; +// } + +// al_lock_mutex(mutex); +// screen[currentScreen]->flipStateBuffer(); +// al_unlock_mutex(mutex); + +// double start_render = al_get_time(); + +// screen[currentScreen]->render(this, delta_time); +// al_flip_display(); +// draw_old_time = al_get_time(); + +// double end_render = al_get_time(); + +// double rest_time = (1.0 / this->FPS - end_render + start_render)/5; +// if (end_render - start_render < 1.0 / this->FPS && rest_time > 0){ +// al_rest(rest_time); +// } +// } +} + +void Game::Engine::loop() { + delta_time = 0.0; + update_old_time = al_get_time(); + + while(!this->endGame) { + double current_time = al_get_time(); + delta_time += current_time - update_old_time; + update_old_time = al_get_time(); + + ALLEGRO_EVENT event; + while (al_get_next_event(this->event_queue, &event)) { + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + this->endGame = true; + } else { + this->screen[this->currentScreen]->handleEvents(this, &event); + } + } + + while (delta_time >= (1.0 / this->UPS)) { + delta_time -= 1.0 / this->UPS; + this->screen[this->currentScreen]->update(this, 1.0 / this->UPS); // parametro em mili + this->update_old_time = al_get_time(); + } + + screen[currentScreen]->render(this, delta_time); + al_flip_display(); + al_rest(0.01); + } +} + +void Game::Engine::addScreen(int index, Screen * screen) { + this->screen[index] = screen; +} + +void Game::Engine::jumpScreen(int index) { + this->screen[this->currentScreen]->stop(this); + this->currentScreen = index; + this->screen[index]->start(this); +} + +//============================================================================== + +void * Game::Engine::updateThread(ALLEGRO_THREAD *thr, void *arg) { + Game::Engine * engine = (Game::Engine *)arg; + + al_start_timer(engine->timerUpdate); + engine->update_old_time = al_get_time(); + + while(!engine->endGame) { + ALLEGRO_EVENT event; + al_wait_for_event(engine->event_queue, &event); + + al_lock_mutex(engine->mutex); + if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + engine->endGame = true; + } + if(event.type == ALLEGRO_EVENT_TIMER) { + engine->screen[engine->currentScreen]->update(engine, 1.0 / engine->UPS); // parametro em mili + engine->update_old_time = al_get_time(); + } else { + engine->screen[engine->currentScreen]->handleEvents(engine, &event); + } + al_unlock_mutex(engine->mutex); + } + + return 0; +} diff --git a/src/engine.h b/src/engine.h new file mode 100644 index 0000000..d7a9e8b --- /dev/null +++ b/src/engine.h @@ -0,0 +1,76 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _ENGINE_ +#define _ENGINE_ + +#include +#include +#include +#include +#include +#include +#include + +namespace Game { + +class Screen; + +class Engine { +public: + static constexpr double FPS = 60.0; // Frame per second + static constexpr double UPS = 60.0; // Update per second + + static constexpr int SCREEN_WIDTH = 720; + static constexpr int SCREEN_HEIGHT = 720; + + static constexpr int SCREEN_SIZE = 30; + Screen *screen[SCREEN_SIZE]; + int currentScreen; + + int gold; + + double delta_time; + double draw_old_time; + double update_old_time; + + bool endGame; + + ALLEGRO_THREAD *thread_update; + ALLEGRO_MUTEX *mutex; + + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *event_queue; + ALLEGRO_TIMER *timerUpdate; + ALLEGRO_SAMPLE *music; + + Engine(); + ~Engine(); + + void run(); + void loop(); + + void addScreen(int index, Screen * screen); + void jumpScreen(int index); + + static void *updateThread(ALLEGRO_THREAD *thr, void *arg); +}; + +} + + +#endif diff --git a/src/entity.cpp b/src/entity.cpp new file mode 100644 index 0000000..d5aa9e6 --- /dev/null +++ b/src/entity.cpp @@ -0,0 +1,78 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "entity.h" +#include "bounding-box.h" +#include "map.h" + +BoundingBox Entity::hasMapCollision(Map *map) { + BoundingBox result = BoundingBox(0, 0, 0, 0); + BoundingBox box = BoundingBox(position.getX() - width / 2, + position.getY() - height / 2, + width, height); + + int tileX = position.getX() / TILESET_WIDTH; + int tileY = position.getY() / TILESET_HEIGHT; + + // colisão com o mapa + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int x = tileX + dx; + int y = tileY + dy; + if (map->tiles[y][x] == WALL) { + BoundingBox tileBox = BoundingBox(x * TILESET_WIDTH, y * TILESET_HEIGHT, + TILESET_WIDTH, TILESET_HEIGHT); + if (box.intersects(tileBox)) { + result = tileBox; + return result; + } + } + } + } + + return result; +} + +Entity *Entity::hasEntityCollision(std::vector entities) { + Entity *result = 0; + BoundingBox box = BoundingBox(position.getX() - width / 2, + position.getY() - height / 2, + width, height); + + // colisão com entidades + if (!result) { + for (unsigned int i = 0; i < entities.size(); i++) { + BoundingBox entityBox = BoundingBox(entities[i]->position.getX() - entities[i]->width / 2, + entities[i]->position.getY() - entities[i]->height / 2, + entities[i]->width, entities[i]->height); + if (box.intersects(entityBox)) { + result = entities[i]; + break; + } + } + } + + return result; +} + +bool Entity::isDead() { + return false; +} + +ParticleSystem *Entity::getDeathParticles() { + return 0; +} diff --git a/src/entity.h b/src/entity.h new file mode 100644 index 0000000..8f9f604 --- /dev/null +++ b/src/entity.h @@ -0,0 +1,57 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef ENTITY_H +#define ENTITY_H + +#include "vector2d.h" +#include "bounding-box.h" +#include "particle-system.h" +#include +#include + +class Map; + +enum EntityType { + PLAYER, MONSTER, ITEM, PROJECTILE +}; + +enum Orientation { + FACING_UP, FACING_LEFT, FACING_RIGHT, FACING_DOWN +}; + +class Entity { + public: + virtual ~Entity() {}; + + int type; + Orientation orientation; + int flags; + Vector2D position; + Vector2D velocity; + int width; + int height; + virtual BoundingBox hasMapCollision(Map *map); + Entity *hasEntityCollision(std::vector entities); + virtual void collisionWith(Entity *entity) = 0; // devolve null se é uma colisão com mapa + virtual void update(double dt, Map *map, std::vector entities) = 0; + virtual void render(double edt) = 0; + virtual bool isDead(); + virtual ParticleSystem *getDeathParticles(); +}; + +#endif // ENTITY_H diff --git a/src/fadein.cpp b/src/fadein.cpp new file mode 100644 index 0000000..3cc9861 --- /dev/null +++ b/src/fadein.cpp @@ -0,0 +1,58 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "fadein.h" +#include "window.h" +#include + +Fadein::Fadein(ALLEGRO_COLOR color, double duration) { + this->color = color; + totalDuration = duration; + curDuration = 0.0; +} + +Fadein::~Fadein() { + +} + +void Fadein::update(double dt) { + curDuration += dt; + if (curDuration > totalDuration) { + curDuration = totalDuration; + } +} + +void Fadein::render(double edt) { + double duration = curDuration + edt; + if (duration > totalDuration) { + duration = totalDuration; + } + + double t = (1.0 - (duration / totalDuration)) * 255.0; + unsigned char a = (unsigned char) t; + unsigned char r, g, b; + al_unmap_rgb(color, &r, &g, &b); + ALLEGRO_COLOR fillColor = al_map_rgba(r, g, b, a); + al_draw_filled_rectangle(0, 0, Window::getInstance()->getWidth(), Window::getInstance()->getHeight(), fillColor); +} + +bool Fadein::isFinished() { + return curDuration == totalDuration; +} + + + diff --git a/src/fadein.h b/src/fadein.h new file mode 100644 index 0000000..e357eaa --- /dev/null +++ b/src/fadein.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _FADE_IN_H +#define _FADE_IN_H + +#include "transition.h" +#include + +class Fadein : public Transition { + private: + ALLEGRO_COLOR color; + double totalDuration; + double curDuration; + + public: + Fadein(ALLEGRO_COLOR color, double duration); + ~Fadein(); + + void update(double dt); + void render(double edt); + bool isFinished(); +}; + +#endif diff --git a/src/fadeout.cpp b/src/fadeout.cpp new file mode 100644 index 0000000..ff89c1b --- /dev/null +++ b/src/fadeout.cpp @@ -0,0 +1,54 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "fadeout.h" +#include "window.h" +#include + +Fadeout::Fadeout(ALLEGRO_COLOR color, double duration) { + this->color = color; + totalDuration = duration; + curDuration = 0.0; +} + +Fadeout::~Fadeout() { + +} + +void Fadeout::update(double dt) { + curDuration += dt; + if (curDuration > totalDuration) { + curDuration = totalDuration; + } +} + +void Fadeout::render(double edt) { + double duration = curDuration + edt; + if (duration > totalDuration) { + duration = totalDuration; + } + + double t = duration / totalDuration; + unsigned char r, g, b; + al_unmap_rgb(color, &r, &g, &b); + ALLEGRO_COLOR fillColor = al_map_rgba(r, g, b, (unsigned char) (t * 255.0)); + al_draw_filled_rectangle(0, 0, Window::getInstance()->getWidth(), Window::getInstance()->getHeight(), fillColor); +} + +bool Fadeout::isFinished() { + return curDuration == totalDuration; +} diff --git a/src/fadeout.h b/src/fadeout.h new file mode 100644 index 0000000..32808f7 --- /dev/null +++ b/src/fadeout.h @@ -0,0 +1,40 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _FADE_OUT_H +#define _FADE_OUT_H + +#include "transition.h" + +#include + +class Fadeout : public Transition { + private: + ALLEGRO_COLOR color; + double totalDuration; + double curDuration; + + public: + Fadeout(ALLEGRO_COLOR color, double duration); + ~Fadeout(); + + void update(double dt); + void render(double edt); + bool isFinished(); +}; + +#endif diff --git a/src/fireball.cpp b/src/fireball.cpp new file mode 100644 index 0000000..94938c9 --- /dev/null +++ b/src/fireball.cpp @@ -0,0 +1,181 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "fireball.h" +#include "mage.h" +#include "window.h" +#include "monster.h" +#include "particle-system.h" + +Fireball::Fireball(Player *player, Orientation orientation, int damage) { + type = PROJECTILE; + this->player = player; + this->orientation = orientation; + this->position = player->position; + this->damage = damage; + + width = 48; + height = 48; + + switch (orientation) { + case FACING_UP: + vel = Vector2D(0, -1); + position = position.add(Vector2D(0, -height / 2)); + break; + case FACING_RIGHT: + vel = Vector2D(1, 0); + position = position.add(Vector2D(width / 2, 0)); + break; + case FACING_DOWN: + vel = Vector2D(0, 1); + position = position.add(Vector2D(0, height / 2)); + break; + case FACING_LEFT: + vel = Vector2D(-1, 0); + position = position.add(Vector2D(-width / 2, 0)); + break; + } + + speed = 384.0; + dead = false; +} + +Fireball::~Fireball() { + +} + +void Fireball::collisionWith(Entity *entity) { + if (entity->type == MONSTER) { + Monster *monster = (Monster *)entity; + monster->slowDuration = 1.0; + if (monster->weakness == ALL || monster->weakness == player->playerType) { + if (monster->immunity <= 0.0) { + monster->playSound(); + monster->life -= damage; + if (monster->life < 0.0) { + monster->life = 0.0; + player->gold += monster->gold; + } + monster->immunity = 0.5; + } + } else { + player->playMissSound(); + } + } +} + +void Fireball::update(double dt, Map *map, std::vector entities) { + position = position.add(vel.mult(speed * dt)); + + Entity *result = 0; + BoundingBox box = BoundingBox(position.getX() - width / 4, + position.getY() - height / 4, + width / 2, height / 2); + + // colisão com entidades + if (!result) { + for (unsigned int i = 0; i < entities.size(); i++) { + if (entities[i]->type == MONSTER) { + BoundingBox entityBox = BoundingBox(entities[i]->position.getX() - entities[i]->width / 2, + entities[i]->position.getY() - entities[i]->height / 2, + entities[i]->width, entities[i]->height); + if (box.intersects(entityBox)) { + result = entities[i]; + dead = true; + break; + } + } + } + } + + if (result) { + collisionWith(result); + } else { + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0 || + box.getMaxY() - box.getMinY()) { + dead = true; + } + } +} + +BoundingBox Fireball::hasMapCollision(Map *map) { + BoundingBox result = BoundingBox(0, 0, 0, 0); + BoundingBox box = BoundingBox(position.getX() - width / 6, + position.getY() - height / 6, + width / 3, height / 3); + + int tileX = position.getX() / TILESET_WIDTH; + int tileY = position.getY() / TILESET_HEIGHT; + + // colisão com o mapa + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int x = tileX + dx; + int y = tileY + dy; + if (map->tiles[y][x] == WALL) { + BoundingBox tileBox = BoundingBox(x * TILESET_WIDTH, y * TILESET_HEIGHT, + TILESET_WIDTH, TILESET_HEIGHT); + if (box.intersects(tileBox)) { + result = tileBox; + return result; + } + } + } + } + + return result; +} + +void Fireball::render(double edt) { + if (!Mage::mage) { + Mage::mage = al_load_bitmap("resources/graphics/warrior.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + switch (orientation) { + case FACING_UP: + al_draw_tinted_scaled_rotated_bitmap_region(Mage::mage, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 0.0, 0); + break; + + case FACING_RIGHT: + al_draw_tinted_scaled_rotated_bitmap_region(Mage::mage, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.14 / 2.0, 0); + break; + + case FACING_DOWN: + al_draw_tinted_scaled_rotated_bitmap_region(Mage::mage, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.14, 0); + break; + + case FACING_LEFT: + al_draw_tinted_scaled_rotated_bitmap_region(Mage::mage, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, 3.0 * 3.14 / 2.0, 0); + break; + } +} + +bool Fireball::isDead() { + return dead; +} diff --git a/src/fireball.h b/src/fireball.h new file mode 100644 index 0000000..060468e --- /dev/null +++ b/src/fireball.h @@ -0,0 +1,45 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef FIREBALL_H +#define FIREBALL_H + +#include "entity.h" +#include "player.h" + +class Fireball : public Entity { +public: + Fireball(Player *player, Orientation orientation, int damage); + ~Fireball(); + + Player *player; + Orientation orientation; + double attackTime; + int damage; + + Vector2D vel; + double speed; + bool dead; + + void collisionWith(Entity *entity); + BoundingBox hasMapCollision(Map *map); + void update(double dt, Map *map, std::vector entities); + void render(double edt); + bool isDead(); +}; + +#endif // FIREBALL_H diff --git a/src/game-over-screen.cpp b/src/game-over-screen.cpp new file mode 100644 index 0000000..dad3457 --- /dev/null +++ b/src/game-over-screen.cpp @@ -0,0 +1,112 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "game-over-screen.h" +#include "fadein.h" +#include "fadeout.h" +#include "window.h" + +namespace Game { + +GameOverScreen::GameOverScreen() { + jumpToGame = false; + + entryTransition = 0; + exitTransition = 0; + title = 0; + curTransition = 0; + + font = 0; +} + +GameOverScreen::~GameOverScreen() { + +} + +void GameOverScreen::start(Engine * engine) { + jumpToGame = false; + entryTransition = new Fadein(al_map_rgb(0, 0, 0), 1.0); + exitTransition = new Fadeout(al_map_rgb(0, 0, 0), 1.0); + curTransition = entryTransition; +} + +void GameOverScreen::stop(Engine * engine) { + +} + +void GameOverScreen::handleEvents(Engine * engine ,ALLEGRO_EVENT *event) { + if (!curTransition) { + if(event->type == ALLEGRO_EVENT_KEY_DOWN) { + + } else if (event->type == ALLEGRO_EVENT_KEY_UP) { + switch (event->keyboard.keycode) { + case ALLEGRO_KEY_ESCAPE: + engine->endGame = true; + break; + + default: + jumpToGame = true; + curTransition = exitTransition; + break; + } + } + } +} + +void GameOverScreen::update(Engine *engine, double dts) { + if (jumpToGame && curTransition) { + if (curTransition->isFinished()) { + engine->jumpScreen(0); + } else { + curTransition->update(dts); + } + } else { + if (curTransition) { + curTransition->update(dts); + if (curTransition->isFinished()) { + curTransition = 0; + } + } + } +} + +void GameOverScreen::render(Engine *engine, double edt) { + if (!title) { + title = al_load_bitmap("resources/graphics/gameover.png"); + } + al_clear_to_color(al_map_rgb(0,0,0)); + al_draw_bitmap(title, 0, 0, 0); + + if (!font) { + font = al_load_ttf_font("resources/fonts/segoepr.ttf", 50, 0); + } + + char timeStr[8]; + sprintf(timeStr, "%d", (int) engine->gold); + al_draw_text(font, al_map_rgb(255, 255, 255), Window::getInstance()->getWidth() / 2, Window::getInstance()->getHeight() / 2, ALLEGRO_ALIGN_CENTRE, timeStr); + + if (curTransition) { + curTransition->render(edt); + } +} + +void GameOverScreen::flipStateBuffer() { + +} + +} + diff --git a/src/game-over-screen.h b/src/game-over-screen.h new file mode 100644 index 0000000..e33481e --- /dev/null +++ b/src/game-over-screen.h @@ -0,0 +1,56 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef GAMEOVERSCREEN_H +#define GAMEOVERSCREEN_H + +#include "game.h" +#include + +class Transition; + +namespace Game { + +class GameOverScreen : public Screen { + private: + ALLEGRO_BITMAP *title; + ALLEGRO_FONT *font; + enum MYKEYS {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT}; + bool jumpToGame; + Transition *entryTransition; + Transition *exitTransition; + Transition *curTransition; + + public: + bool key[4]; + int treasure; + + GameOverScreen(); + ~GameOverScreen(); + + void start(Engine * engine); + void stop(Engine * engine); + + void handleEvents(Engine * engine ,ALLEGRO_EVENT *event); + void update(Engine * engine ,double dts); + void render(Engine * engine ,double edt); + void flipStateBuffer(); +}; + +} + +#endif // GAMEOVERSCREEN_H diff --git a/src/game-screen.cpp b/src/game-screen.cpp new file mode 100644 index 0000000..db9caa5 --- /dev/null +++ b/src/game-screen.cpp @@ -0,0 +1,508 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "game-screen.h" +#include "warrior.h" +#include "rogue.h" +#include "mage.h" +#include "window.h" +#include "spider.h" +#include "construct.h" +#include "minotaur.h" +#include "ghost.h" +#include "witch.h" +#include "bat.h" +#include "zombie.h" +#include "medusa.h" +#include "goblin.h" +#include "potion-change.h" +#include "potion.h" +#include "gold.h" +#include +#include +#include "boots.h" +#include "item.h" +#include "potion.h" +#include "potion-change.h" +#include "potion-haste.h" +#include "potion-slow.h" +#include "sword.h" +#include "amulet.h" +#include "potion-poison.h" + +namespace Game { + +GameScreen::GameScreen() { + font = 0; + smallFont = 0; + playerHud = 0; + darkness = 0; +} + +GameScreen::~GameScreen() { + +} + +int GameScreen::numRand(int minF, int maxF) { + int interval = maxF - minF + 1; + return (minF + int(interval * (double)rand() /((double)RAND_MAX + 1.0)) ); +} + +void GameScreen::selectPlayers() { + int p1 = numRand(0,2); + int p2 = p1; + while(p1 == p2) { + p2 = numRand(0,2); + } + switch(p1) { + case MAGE: + player[0] = new Mage(); + break; + case WARRIOR: + player[0] = new Warrior(); + break; + case ROGUE: + player[0] = new Rogue(); + break; + } + + switch(p2) { + case MAGE: + player[1] = new Mage(); + break; + case WARRIOR: + player[1] = new Warrior(); + break; + case ROGUE: + player[1] = new Rogue(); + break; + } + + map->positionInside(player[0]); + player[1]->position = player[0]->position; + + entities.push_back(player[0]); + entities.push_back(player[1]); +} + +void GameScreen::selectMonsters(void) { + int monsterIndice; + + for(int i = 0; i < 40; i++) { + Entity* moster; + monsterIndice = numRand(0,8); + switch(monsterIndice) { + case SPIDER: + moster = new Spider(); + break; + case BAT: + moster = new Bat(); + break; + case MINOTAUR: + moster = new Minotaur(); + break; + case CONSTRUCT: + moster = new Construct(); + break; + case WITCH: + moster = new Witch(); + break; + case ZOMBIE: + moster = new Zombie(); + break; + case MEDUSA: + moster = new Medusa(); + break; + case GOBLIN: + moster = new Goblin(); + break; + case GHOST: + moster = new Ghost(); + break; + default: + moster = new Spider(); + break; + } + + map->positionInside(moster); + entities.push_back(moster); + } +} + +void GameScreen::selectItems(void) { + int itemIndice; + + for(int i = 0; i < 40; i++) { + Entity* item; + itemIndice = numRand(1,9); + switch(itemIndice) { + + case POTION_LIFE: + item = new PotionLife(); + break; + case POTION_POISON: + item = new PotionPoison(); + break; + case POTION_SLOW: + item = new PotionSlow(); + break; + case POTION_HASTE: + item = new PotionHaste(); + break; + case POTION_SWAP: + item = new PotionChange(); + break; + case BOOTS_OF_SPEED: + item = new Boots(); + break; + case AMULET: + item = new Amulet(); + break; + case HELMET: + item = new Sword(); + break; + case GOLD: + item = new Gold(); + break; + default: + item = new Boots(); + break; + } + + map->positionInside(item); + entities.push_back(item); + } + + for(int i = 0; i < 100; i++) { + Entity* item; + item = new Gold(); + map->positionInside(item); + entities.push_back(item); + } +} + + +void GameScreen::start(Engine * engine) { + map = new Map(); + + entities.clear(); + particleSystems.clear(); + + selectPlayers(); + selectMonsters(); + selectItems(); + + remainingTime = 60.0; + font = 0; + al_play_sample(engine->music, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_LOOP, NULL); + + if (!playerHud) { + playerHud = al_load_bitmap("resources/graphics/playerhud.png"); + } + + if (!darkness) { + darkness = al_load_bitmap("resources/graphics/darkness.png"); + } +} + +void GameScreen::stop(Engine * engine) { + al_stop_samples(); +} + +void GameScreen::handleEvents(Engine * engine ,ALLEGRO_EVENT *event) { + if(event->type == ALLEGRO_EVENT_KEY_DOWN) { + switch(event->keyboard.keycode) { + case ALLEGRO_KEY_UP: + player[1]->inputEvent(UP_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_DOWN: + player[1]->inputEvent(DOWN_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_LEFT: + player[1]->inputEvent(LEFT_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_RIGHT: + player[1]->inputEvent(RIGHT_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_I: + player[1]->inputEvent(BUT1_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_O: + player[1]->inputEvent(BUT2_PRESS, map, entities,player); + if (player[1]->usedItem) { + ParticleSystem *particleSystem = player[1]->usedItem->getUseParticles(); + if (particleSystem) { + particleSystems.push_back(particleSystem); + } + player[1]->usedItem = 0; + } + break; + + case ALLEGRO_KEY_P: + player[1]->inputEvent(BUT3_PRESS, map, entities,player); + if (player[1]->usedItem) { + ParticleSystem *particleSystem = player[1]->usedItem->getUseParticles(); + if (particleSystem) { + particleSystems.push_back(particleSystem); + } + player[1]->usedItem = 0; + } + break; + + case ALLEGRO_KEY_T: + player[0]->inputEvent(BUT2_PRESS, map, entities,player); + if (player[0]->usedItem) { + ParticleSystem *particleSystem = player[0]->usedItem->getUseParticles(); + if (particleSystem) { + particleSystems.push_back(particleSystem); + } + player[0]->usedItem = 0; + } + break; + + case ALLEGRO_KEY_Y: + player[0]->inputEvent(BUT3_PRESS, map, entities,player); + if (player[0]->usedItem) { + ParticleSystem *particleSystem = player[0]->usedItem->getUseParticles(); + if (particleSystem) { + particleSystems.push_back(particleSystem); + } + player[0]->usedItem = 0; + } + break; + + case ALLEGRO_KEY_W: + player[0]->inputEvent(UP_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_S: + player[0]->inputEvent(DOWN_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_A: + player[0]->inputEvent(LEFT_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_D: + player[0]->inputEvent(RIGHT_PRESS, map, entities,player); + break; + + case ALLEGRO_KEY_R: + player[0]->inputEvent(BUT1_PRESS, map, entities,player); + break; + } + } else if(event->type == ALLEGRO_EVENT_KEY_UP) { + switch(event->keyboard.keycode) { + case ALLEGRO_KEY_UP: + player[1]->inputEvent(UP_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_DOWN: + player[1]->inputEvent(DOWN_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_LEFT: + player[1]->inputEvent(LEFT_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_RIGHT: + player[1]->inputEvent(RIGHT_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_W: + player[0]->inputEvent(UP_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_S: + player[0]->inputEvent(DOWN_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_A: + player[0]->inputEvent(LEFT_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_D: + player[0]->inputEvent(RIGHT_RELEASE, map, entities,player); + break; + + case ALLEGRO_KEY_ESCAPE: + engine->endGame = true; + break; + } + } +} + +void GameScreen::update(Engine *engine, double dts) { + std::vector entitiesToAdd; + + std::vector::iterator it = entities.begin(); + while (it != entities.end()) { + Entity *entity = (*it); + if (entity->isDead()) { + ParticleSystem *partSys = entity->getDeathParticles(); + if (partSys) { + particleSystems.push_back(partSys); + } + it = entities.erase(it); + } else { + entity->update(dts, map, entities); + + if (player[0] == entity) { + if (player[0]->projectile) { + entitiesToAdd.push_back(player[0]->projectile); + player[0]->projectile = 0; + } + } else if (player[1] == entity) { + if (player[1]->projectile) { + entitiesToAdd.push_back(player[1]->projectile); + player[1]->projectile = 0; + } + } + + it++; + } + } + + Vector2D windowCenter = Vector2D((player[0]->position.getX() + player[1]->position.getX()) / 2, + (player[0]->position.getY() + player[1]->position.getY()) / 2); + Window *window = Window::getInstance(); + window->windowPos = windowCenter; + + std::vector::iterator itp = particleSystems.begin(); + while (itp != particleSystems.end()) { + ParticleSystem *particleSystem = (*itp); + if (particleSystem->isDead()) { + itp = particleSystems.erase(itp); + } else { + particleSystem->update(dts); + itp++; + } + } + + for (unsigned int i = 0; i < entitiesToAdd.size(); i++) { + entities.push_back((entitiesToAdd[i])); + } + + remainingTime -= dts; + if (remainingTime < 0.0) { + remainingTime = 0.0; + } + + if (remainingTime <= 0.0 || player[0]->life <= 0.0 || player[1]->life <= 0.0) { + engine->gold = player[0]->gold + player[1]->gold; + engine->jumpScreen(3); + } +} + +void GameScreen::render(Engine *engine, double edt) { + al_clear_to_color(al_map_rgb(0,0,0)); + map->render(); + for (unsigned int i = 0; i < entities.size(); i++) { + entities[i]->render(edt); + } + for (unsigned int i = 0; i < particleSystems.size(); i++) { + particleSystems[i]->render(edt); + } + + if (!font) { + font = al_load_ttf_font("resources/fonts/segoepr.ttf", 50, 0); + } + + if (!smallFont) { + smallFont = al_load_ttf_font("resources/fonts/segoepr.ttf", 16, 0); + } + + al_draw_tinted_scaled_bitmap(darkness, al_map_rgb(255, 255, 255), + 0, 0, 640, 360, + 0, 0, 1280, 720, 0); + + char timeStr[8]; + sprintf(timeStr, "%d", (int) remainingTime); + al_draw_text(font, al_map_rgb(255, 255, 255), Window::getInstance()->getWidth() / 2, 20, ALLEGRO_ALIGN_CENTRE, timeStr); + + drawPlayerHud(); +} + +void GameScreen::drawPlayerHud() { + char gold1Str[8]; + sprintf(gold1Str, "%d", (int) player[0]->gold); + al_draw_text(smallFont, al_map_rgb(255, 255, 255), 20 + 25, 20 + 96, ALLEGRO_ALIGN_CENTRE, gold1Str); + + al_draw_text(smallFont, al_map_rgb(255, 255, 255), 20 + 56, 20, ALLEGRO_ALIGN_LEFT, player[0]->getName().c_str()); + + int whitebarWidth = ((double) player[0]->lifeBar / (double) player[0]->maxLife) * 116.0; + int redbarWidth = ((double) player[0]->life / (double) player[0]->maxLife) * 116.0; + + al_draw_filled_rectangle(20 + 58, 20 + 26, 20 + 58 + whitebarWidth, 20 + 26 + 16, al_map_rgb(255, 255, 255)); + al_draw_filled_rectangle(20 + 58, 20 + 26, 20 + 58 + redbarWidth, 20 + 26 + 16, al_map_rgb(255, 0, 0)); + + int slotX = 80; + int slotY = 76; + for (int i = 0; i < player[0]->maxSlots; i++) { + if (player[0]->items[i]) { + player[0]->items[i]->renderScreen(slotX + i * 64, slotY); + } + } + + if (player[0]->maxSlots == 2) { + al_draw_tinted_scaled_bitmap(playerHud, al_map_rgb(255, 255, 255), + 0, 0, 184, 120, + 20, 20, 184, 120, 0); + } else { + al_draw_tinted_scaled_bitmap(playerHud, al_map_rgb(255, 255, 255), + 0, 120, 184, 120, + 20, 20, 184, 120, 0); + } + player[0]->renderScreen(20, 20); + + char gold2Str[8]; + sprintf(gold2Str, "%d", (int) player[1]->gold); + al_draw_text(smallFont, al_map_rgb(255, 255, 255), 1280 - 20 - 25, 20 + 96, ALLEGRO_ALIGN_CENTRE, gold2Str); + + al_draw_text(smallFont, al_map_rgb(255, 255, 255), 1280 - 20 - 56, 20, ALLEGRO_ALIGN_RIGHT, player[1]->getName().c_str()); + + whitebarWidth = ((double) player[1]->lifeBar / (double) player[1]->maxLife) * 116.0; + redbarWidth = ((double) player[1]->life / (double) player[1]->maxLife) * 116.0; + + al_draw_filled_rectangle(1280 - 20 - 58 - whitebarWidth, 20 + 26, 1280 - 20 - 58, 20 + 26 + 16, al_map_rgb(255, 255, 255)); + al_draw_filled_rectangle(1280 - 20 - 58 - redbarWidth, 20 + 26, 1280 - 20 - 58, 20 + 26 + 16, al_map_rgb(255, 0, 0)); + + slotX = 174; + slotY = 76; + for (int i = 0; i < player[1]->maxSlots; i++) { + if (player[1]->items[i]) { + player[1]->items[i]->renderScreen(1280 - 20 - slotX + i * 64, slotY); + } + } + + if (player[1]->maxSlots == 2) { + al_draw_tinted_scaled_bitmap(playerHud, al_map_rgb(255, 255, 255), + 184, 0, 184, 120, + 1280 - 184 - 20, 20, 184, 120, 0); + } else { + al_draw_tinted_scaled_bitmap(playerHud, al_map_rgb(255, 255, 255), + 184, 120, 184, 120, + 1280 - 184 - 20, 20, 184, 120, 0); + } + player[1]->renderScreen(1280 - 20 - 48, 20); +} +} diff --git a/src/game-screen.h b/src/game-screen.h new file mode 100644 index 0000000..9f05777 --- /dev/null +++ b/src/game-screen.h @@ -0,0 +1,62 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _GAME_SCREEN_H +#define _GAME_SCREEN_H + +#include "game.h" +#include "map.h" +#include "entity.h" +#include "player.h" +#include "particle-system.h" +#include +#include + +namespace Game { + +class GameScreen : public Screen { +private: + std::vector entities; + Map *map; + Player *player[2]; + std::vector particleSystems; + double remainingTime; + ALLEGRO_FONT *font; + ALLEGRO_FONT *smallFont; + ALLEGRO_BITMAP *playerHud; + ALLEGRO_BITMAP *darkness; + +public: + GameScreen(); + ~GameScreen(); + + void start(Engine * engine); + void stop(Engine * engine); + + void handleEvents(Engine * engine ,ALLEGRO_EVENT *event); + void update(Engine * engine ,double dts); + void render(Engine * engine ,double edt); + int numRand(int min, int max); + void selectPlayers(void); + void selectMonsters(void); + void selectItems(void); + void drawPlayerHud(); +}; + +} + +#endif diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 0000000..4fabf7b --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,18 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "game.h" diff --git a/src/game.h b/src/game.h new file mode 100644 index 0000000..6b078c3 --- /dev/null +++ b/src/game.h @@ -0,0 +1,44 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _GAME_ +#define _GAME_ + +#include "engine.h" +#include +#include + +namespace Game { + +class Screen { +public: + static const int BACK_BUFFER = 0; + static const int FRONT_BUFFER = 1; + + virtual ~Screen() {}; + + virtual void start(Engine * engine) = 0; + virtual void stop(Engine * engine) = 0; + + virtual void handleEvents(Engine * engine ,ALLEGRO_EVENT *event) = 0; + virtual void update(Engine * engine ,double deltaTimeSecond) = 0; + virtual void render(Engine * engine ,double deltaTimeSecond) = 0; +}; + +} + +#endif diff --git a/src/ghost.cpp b/src/ghost.cpp new file mode 100644 index 0000000..d7250aa --- /dev/null +++ b/src/ghost.cpp @@ -0,0 +1,102 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "ghost.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Ghost::ghost = 0; +ALLEGRO_SAMPLE *Ghost::sound = 0; + +Ghost::Ghost() { + life = 60; + power = 20; + speed = 192; + maxSpeed = speed; + weakness = ALL; + width = 48; + height = 48; + gold = 2; +} + +Ghost::~Ghost() { +} + +BoundingBox Ghost::hasMapCollision(Map *map) { + BoundingBox result = BoundingBox(0, 0, 0, 0); + BoundingBox box = BoundingBox(position.getX() - width / 2, + position.getY() - height / 2, + width, height); + + int tileX = position.getX() / TILESET_WIDTH; + int tileY = position.getY() / TILESET_HEIGHT; + + // colisão com o mapa + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int x = tileX + dx; + int y = tileY + dy; + if (x == TILESET_WIDTH - 1 || x == 0 || y == 0 || y == TILESET_HEIGHT - 1) { + BoundingBox tileBox = BoundingBox(x * TILESET_WIDTH, y * TILESET_HEIGHT, + TILESET_WIDTH, TILESET_HEIGHT); + if (box.intersects(tileBox)) { + result = tileBox; + return result; + } + } + } + } + + return result; +} + +void Ghost::render(double edt) { + if (!ghost) { + ghost = al_load_bitmap("resources/graphics/ghost.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(ghost, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(ghost, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Ghost::getDeathParticles() { + Particle *particle = new Particle(0, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, -300, 0.5); + + return particleSystem; +} + +void Ghost::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/ghost.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/ghost.h b/src/ghost.h new file mode 100644 index 0000000..1d0a582 --- /dev/null +++ b/src/ghost.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef GHOST_H +#define GHOST_H + +#include "monster.h" +#include +#include + +class Ghost : public Monster { +public: + static ALLEGRO_BITMAP *ghost; + static ALLEGRO_SAMPLE *sound; + + Ghost(); + ~Ghost(); + + BoundingBox hasMapCollision(Map *map); + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // GHOST_H diff --git a/src/goblin.cpp b/src/goblin.cpp new file mode 100644 index 0000000..621963b --- /dev/null +++ b/src/goblin.cpp @@ -0,0 +1,75 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "goblin.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Goblin::goblin = 0; +ALLEGRO_SAMPLE *Goblin::sound = 0; + +Goblin::Goblin() { + life = 30; + power = 10; + speed = 320; + maxSpeed = speed; + weakness = ROGUE; + width = 48; + height = 48; + gold = 3; +} + +Goblin::~Goblin() { +} + +void Goblin::render(double edt) { + if (!goblin) { + goblin = al_load_bitmap("resources/graphics/goblin.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(goblin, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(goblin, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Goblin::getDeathParticles() { + Particle *particle = new Particle(7, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Goblin::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/goblin.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + diff --git a/src/goblin.h b/src/goblin.h new file mode 100644 index 0000000..b2bb91a --- /dev/null +++ b/src/goblin.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef GOBLIN_H +#define GOBLIN_H + +#include "monster.h" +#include +#include + +class Goblin : public Monster { +public: + static ALLEGRO_BITMAP *goblin; + static ALLEGRO_SAMPLE *sound; + + Goblin(); + ~Goblin(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // GOBLIN_H diff --git a/src/gold.cpp b/src/gold.cpp new file mode 100644 index 0000000..f67a091 --- /dev/null +++ b/src/gold.cpp @@ -0,0 +1,75 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "gold.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *Gold::goldSound = 0; + +Gold::Gold():Item(GOLD) { +} + +Gold::~Gold() { +} + +void Gold::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + GOLD * width, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void Gold::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player* use; + if(eu->type == player[0]->type) { + use = player[1]; + } else { + use = player[0]; + } + + use->life += 10; +} + +void Gold::collisionWith(Entity *entity) { + if(entity->type == PLAYER && !this->remove) { + Player *p = ((Player*)entity); + p->gold++; + this->remove = true; + + if (!goldSound) { + goldSound = al_load_sample("resources/sound/gold.wav"); + } + + al_play_sample(goldSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); + } +} + +ParticleSystem *Gold::getDeathParticles() { + Particle *particle = new Particle(9, 32, 32, 0.015, 1.0, 0.3, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, UP_CONSTANT, position, 160, 0, 0.2); + + return particleSystem; +} + diff --git a/src/gold.h b/src/gold.h new file mode 100644 index 0000000..6af1d66 --- /dev/null +++ b/src/gold.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef GOLD_H +#define GOLD_H + +#include "item.h" +#include +#include + +class Gold : public Item +{ +public: + static ALLEGRO_SAMPLE *goldSound; + + Gold(); + ~Gold(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + void collisionWith(Entity *entity); + ParticleSystem *getDeathParticles(); +}; + +#endif // GOLD_H diff --git a/src/info-screen.cpp b/src/info-screen.cpp new file mode 100644 index 0000000..90d7219 --- /dev/null +++ b/src/info-screen.cpp @@ -0,0 +1,99 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "info-screen.h" +#include "fadein.h" +#include "fadeout.h" + +namespace Game { + +InfoScreen::InfoScreen() { + jumpToGame = false; + + entryTransition = 0; + exitTransition = 0; + info = 0; + curTransition = 0; +} + +InfoScreen::~InfoScreen() { + +} + +void InfoScreen::start(Engine * engine) { + jumpToGame = false; + entryTransition = new Fadein(al_map_rgb(0, 0, 0), 1.0); + exitTransition = new Fadeout(al_map_rgb(0, 0, 0), 1.0); + curTransition = entryTransition; +} + +void InfoScreen::stop(Engine * engine) { + +} + +void InfoScreen::handleEvents(Engine * engine ,ALLEGRO_EVENT *event) { + if (!curTransition) { + if(event->type == ALLEGRO_EVENT_KEY_DOWN) { + + } else if (event->type == ALLEGRO_EVENT_KEY_UP) { + switch (event->keyboard.keycode) { + case ALLEGRO_KEY_ESCAPE: + engine->endGame = true; + break; + + default: + jumpToGame = true; + curTransition = exitTransition; + break; + } + } + } +} + +void InfoScreen::update(Engine *engine, double dts) { + if (jumpToGame && curTransition) { + if (curTransition->isFinished()) { + engine->jumpScreen(2); + } else { + curTransition->update(dts); + } + } else { + if (curTransition) { + curTransition->update(dts); + if (curTransition->isFinished()) { + curTransition = 0; + } + } + } +} + +void InfoScreen::render(Engine *engine, double edt) { + if (!info) { + info = al_load_bitmap("resources/graphics/instructions.png"); + } + al_clear_to_color(al_map_rgb(0,0,0)); + al_draw_bitmap(info, 0, 0, 0); + if (curTransition) { + curTransition->render(edt); + } +} + +void InfoScreen::flipStateBuffer() { + +} + +} diff --git a/src/info-screen.h b/src/info-screen.h new file mode 100644 index 0000000..8585a70 --- /dev/null +++ b/src/info-screen.h @@ -0,0 +1,54 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef INFOSCREEN_H +#define INFOSCREEN_H + +#include "game.h" +#include + +class Environment; +class Transition; + +namespace Game { + +class InfoScreen : public Screen { + private: + ALLEGRO_BITMAP *info; + enum MYKEYS {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT}; + bool jumpToGame; + Transition *entryTransition; + Transition *exitTransition; + Transition *curTransition; + + public: + bool key[4]; + + InfoScreen(); + ~InfoScreen(); + + void start(Engine * engine); + void stop(Engine * engine); + + void handleEvents(Engine * engine ,ALLEGRO_EVENT *event); + void update(Engine * engine ,double dts); + void render(Engine * engine ,double edt); + void flipStateBuffer(); +}; + +} +#endif // INFOSCREEN_H diff --git a/src/item.cpp b/src/item.cpp new file mode 100644 index 0000000..5757cc0 --- /dev/null +++ b/src/item.cpp @@ -0,0 +1,93 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "item.h" +#include "window.h" + +ALLEGRO_BITMAP *Item::items = 0; +ALLEGRO_SAMPLE *Item::sound = 0; + +Item::Item(int typeItem) { + this->typeItem = typeItem; + this->type = ITEM; + this->remove = false; + width = 48; + height = 48; + orientation = FACING_UP; + flags = 0; + target = 0; +} + +Item::~Item() { +} + +void Item::collisionWith(Entity *entity) { + if(entity->type == PLAYER && !this->remove) { + for(int i = 0; i < ((Player*)entity)->maxSlots; i++) { + Player *p = ((Player*)entity); + if(p->slots[i] == EMPTY) { + ((Player*)entity)->slots[i] = typeItem; + ((Player*)entity)->items[i] = this; + this->remove = true; + + if (!sound) { + sound = al_load_sample("resources/sound/loot.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); + + break; + } + } + } +} + +void Item::update(double dt, Map *map, std::vector entities) { + Entity *entity = hasEntityCollision(entities); + if (entity) { + collisionWith(entity); + } +} + +bool Item::isDead() { + return remove; +} + +void Item::renderScreen(int x, int y) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + typeItem * width, 0, width, height, + x, y, width, height, flags); +} + +ParticleSystem *Item::getDeathParticles() { + return 0; +} + +ParticleSystem *Item::getUseParticles() { + return 0; +} + +void Item::playUseSound() { + +} diff --git a/src/item.h b/src/item.h new file mode 100644 index 0000000..57b7e1b --- /dev/null +++ b/src/item.h @@ -0,0 +1,63 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef ITEM_H +#define ITEM_H + +#include "entity.h" +#include "map.h" +#include +#include + +#define EMPTY -1 +#define CHEST 0 +#define GOLD 1 +#define AMULET 2 +#define BOOTS_OF_SPEED 3 +#define HELMET 4 +#define POTION_LIFE 5 +#define POTION_POISON 6 +#define POTION_HASTE 7 +#define POTION_SLOW 8 +#define POTION_SWAP 9 + + +class Player; + +class Item : public Entity { +public: + static ALLEGRO_BITMAP *items; + static ALLEGRO_SAMPLE *sound; + + Item(int type); + ~Item(); + + int typeItem; + bool remove; + Entity *target; + + virtual void action( Map *map, std::vector entities, Player **player, Player* eu) = 0; + void update(double dt, Map *map, std::vector entities); + void collisionWith(Entity *entity); + bool isDead(); + void renderScreen(int x, int y); + virtual ParticleSystem *getDeathParticles(); + virtual ParticleSystem *getUseParticles(); + virtual void playUseSound(); +}; + +#endif // ITEM_H diff --git a/src/mage.cpp b/src/mage.cpp new file mode 100644 index 0000000..d0e654b --- /dev/null +++ b/src/mage.cpp @@ -0,0 +1,91 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "mage.h" +#include "window.h" +#include "fireball.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Mage::mage = 0; + +Mage::Mage() { + life = 100; + lifeBar = life; + power = 40; + speed = 300; + maxLife = life; + + attackTime = 0.0; + isAttacking = false; + + playerType = MAGE; +} + +Mage::~Mage() { + +} + +std::string Mage::getName() { + return "Mage"; +} + +void Mage::collisionWith(Entity *entity) { + +} + +void Mage::render(double edt) { + if (!mage) { + mage = al_load_bitmap("resources/graphics/mage.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(mage, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(mage, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +void Mage::renderScreen(int x, int y) { + if (!mage) { + mage = al_load_bitmap("resources/graphics/mage.png"); + } + + al_draw_tinted_scaled_bitmap(mage, al_map_rgb(255, 255, 255), + 0, 0, width, height, + x, y, width, height, 0); +} + +void Mage::prepareAttack() { + attackCooldown = FIREBALL_COOLDOWN; + projectile = new Fireball(this, orientation, power); + + if (!Player::fireballSound) { + Player::fireballSound = al_load_sample("resources/sound/fireball.wav"); + } + + al_play_sample(Player::fireballSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/mage.h b/src/mage.h new file mode 100644 index 0000000..c5dde47 --- /dev/null +++ b/src/mage.h @@ -0,0 +1,41 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MAGE_H +#define MAGE_H + +#include "player.h" +#include + +const double FIREBALL_COOLDOWN = 0.5; + +class Mage : public Player { +public: + static ALLEGRO_BITMAP *mage; + double attackTime; + + Mage(); + ~Mage(); + + std::string getName(); + void collisionWith(Entity *entity); + void render(double edt); + void prepareAttack(); + void renderScreen(int x, int y); +}; + +#endif // MAGE_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..895ff90 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,43 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "engine.h" +#include "title-screen.h" +#include "info-screen.h" +#include "game-screen.h" +#include "game-over-screen.h" + +// Alex Campos - A3 Studios +// Ronaldo Rodrigues da Silva + +using namespace Game; + +int main(int argc, char **argv) { + Engine *engine = new Engine(); + Screen *titleScreen = new TitleScreen(); + Screen *infoScreen = new InfoScreen(); + Screen *gameScreen = new GameScreen(); + Screen *gameOverScreen = new GameOverScreen(); + + engine->addScreen(0, titleScreen); + engine->addScreen(1, infoScreen); + engine->addScreen(2, gameScreen); + engine->addScreen(3, gameOverScreen); + engine->run(); + + return 0; +} diff --git a/src/map.cpp b/src/map.cpp new file mode 100644 index 0000000..aec8637 --- /dev/null +++ b/src/map.cpp @@ -0,0 +1,88 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "map.h" +#include "maze-generator.h" +#include "window.h" +#include "bounding-box.h" + +ALLEGRO_BITMAP *Map::tileset = 0; + +Map::Map() { + MazeGenerator mazeGen; + mazeGen.generateMaze(); + for (int y = 0; y < MAX_MAP_HEIGHT; y++) { + for (int x = 0; x < MAX_MAP_WIDTH; x++) { + tiles[y][x] = mazeGen.maze[y][x]; + } + } + + Window *window = Window::getInstance(); + window->windowPos = Vector2D(window->getWidth() / 2, + window->getHeight() / 2 + ); + + int r = rand() % 128; + int g = rand() % 128; + int b = rand() % 128; + color = al_map_rgb(96 + r, 96 + g, 96 + b); +} + +Map::~Map() { + +} + +void Map::render() { + if (!tileset) { + tileset = al_load_bitmap("resources/graphics/tileset.png"); + } + + + Window *window = Window::getInstance(); + BoundingBox bounds = window->getBounds(); + int sx = (bounds.getMinX() / TILESET_WIDTH) - 1; + int sy = (bounds.getMinY() / TILESET_HEIGHT) - 1; + int ex = (bounds.getMaxX() / TILESET_WIDTH) + 1; + int ey = (bounds.getMaxY() / TILESET_HEIGHT) + 1; + + for (int y = sy; y <= ey; y++) { + for (int x = sx; x <= ex; x++) { + if (x < 0 || x >= MAX_MAP_WIDTH || y < 0 || y >= MAX_MAP_HEIGHT) { + continue; + } + Vector2D tilePos = window->getWindowPos(Vector2D(x * TILESET_WIDTH, y * TILESET_HEIGHT)); + al_draw_tinted_scaled_bitmap(tileset, color, + 0, tiles[y][x] * TILESET_HEIGHT, TILESET_WIDTH, TILESET_HEIGHT, + tilePos.getX(), tilePos.getY(), TILESET_WIDTH, TILESET_HEIGHT, 0); + } + } +} + +void Map::positionInside(Entity *entity) +{ + int interval = 63 - 0 + 1; + int ppx = (0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)) ); + int ppy = (0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)) ); + + while(tiles[ppy][ppx] != FLOOR) { + ppx = (0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)) ); + ppy = (0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)) ); + } + + entity->position = Vector2D(ppx * TILESET_WIDTH + TILESET_WIDTH / 2, + ppy * TILESET_HEIGHT + TILESET_HEIGHT / 2); +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..4b34238 --- /dev/null +++ b/src/map.h @@ -0,0 +1,46 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MAP_H +#define MAP_H + +#include "vector2d.h" +#include "player.h" +#include + +const int MAX_MAP_WIDTH = 64; +const int MAX_MAP_HEIGHT = 64; + +const int TILESET_WIDTH = 64; +const int TILESET_HEIGHT = 64; + +enum TileType { WALL, FLOOR }; + +class Map { +public: + static ALLEGRO_BITMAP *tileset; + int tiles[MAX_MAP_HEIGHT][MAX_MAP_WIDTH]; + ALLEGRO_COLOR color; + + Map(); + ~Map(); + + void render(); + void positionInside(Entity *entity); +}; + +#endif // MAP_H diff --git a/src/maze-generator.cpp b/src/maze-generator.cpp new file mode 100644 index 0000000..a4d0c93 --- /dev/null +++ b/src/maze-generator.cpp @@ -0,0 +1,184 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "maze-generator.h" +#include +#include + +using namespace std; + +MazeGenerator::MazeGenerator() +{ + srand(time(0)); + once = false; +} + +MazeGenerator::~MazeGenerator() +{ + +} + +void MazeGenerator::generateMaze(void) +{ + for(int x = 0; x < XSIZE; x++) { + for(int y = 0; y < YSIZE; y++) { + maze[x][y] = WALL; + } + } + + int x; + int y; + int sx; + int sy; + int px; + int py; + int dx; + int dy; + + //Create initial room + + Fill(47,47,53,53,FLOOR); + + for(int i = 0; i < ATTEMPT_FEATURES; i++) { + for(;;) { + //find insertion point + x = random(XSIZE); + y = random(YSIZE); + if(IsWall(x,y,dx,dy)) break; + } + + sx = random(3)+3; + sy = random(3)+3; + + //make corridor + + if(random(10) < 5) { + if(random(2) == 0) { + sx = 1; + sy *= 2; + } else { + sy = 1; + sx *= 2; + } + } + + if(dx == 0) { + px = x-(sx/2); + if(dy > 0) { + py = y +dy; + } else { + py = y - sy ; + } + } else { + py = y-(sy/2); + if(dx > 0) { + px = x+dx ; + } else { + px = x - sx ; + } + } + + + if(CanAdd(px-1,py-1,px+sx+1,py+sy+1) == true) { + maze[x][y] = FLOOR; +// if(random(10) == 2) maze[x][y] = DOOR; + Fill(px,py,px+sx,py+sy, FLOOR); + // if(sx > 1 && sy > 1) Blur(px-2,py-2,px+sx+2,py+sy+2); + } + + } + + for(int x = 0; x < XSIZE; x++) { + for(int y = 0; y < YSIZE; y++) { + if(x == 0 || y == 0 || x == XSIZE - 1 || y == YSIZE - 1) { + maze[x][y] = WALL; + } + } + } +} + + +void MazeGenerator::Fill(int x1, int y1, int x2, int y2, int val) +{ + for(int x = x1; x < x2; x++) { + for(int y = y1; y < y2; y++) { + maze[x][y] = val; + } + } + +} + +bool MazeGenerator::IsWall(int x, int y, int &dx, int &dy) +{ + int spaces = 0; + + if(maze[x][y] != WALL) return false; + + if(x <= 0 || x >= XSIZE) return false; + if(y <= 0 || y >= YSIZE) return false; + + if(maze[x+1][y] == FLOOR) dx = -1, dy = 0, spaces++; + if(maze[x-1][y] == FLOOR) dx = 1, dy = 0,spaces++; + if(maze[x][y+1] == FLOOR) dx = 0, dy = -1,spaces++; + if(maze[x][y-1] == FLOOR) dx = 0, dy = 1,spaces++; + + if(spaces == 1) return true; + return false; + +} + +bool MazeGenerator::CanAdd(int x1, int y1, int x2, int y2) +{ + for(int x = x1; x < x2; x++) { + for(int y = y1; y < y2; y++) { + if(x <= 0 || x >= XSIZE) return false; + if(y <= 0 || y >= YSIZE) return false; + + if(maze[x][y] != WALL) return false; + } + } + + return true; +} + +int MazeGenerator::random(int num) +{ + return int(rand()%num); + +} + +int MazeGenerator::negpo(void) +{ + if(random(2) == 0) { + return -1; + } else { + return 1; + } +} + +void MazeGenerator::Blur(int x1, int y1, int x2, int y2) +{ + int c,x,y; + for(int i = 0; i < 30; i++) { + x = random(x2-x1)+x1; + y = random(y2-y1)+y1; + + if(IsWall(x,y,c,c) == true) maze[x][y] = FLOOR; + } + + return; +} diff --git a/src/maze-generator.h b/src/maze-generator.h new file mode 100644 index 0000000..953abac --- /dev/null +++ b/src/maze-generator.h @@ -0,0 +1,49 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _MAZE_GENERATOR_ +#define _MAZE_GENERATOR_ + +#define XSIZE 64 +#define YSIZE 64 + +#define TILESIZE 64 + +#define ATTEMPT_FEATURES 4000 + +#define WALL 0 +#define FLOOR 1 +#define DOOR 2 + +class MazeGenerator { +public: + MazeGenerator(); + ~MazeGenerator(); + + int maze[XSIZE][YSIZE]; + bool once; + + void generateMaze(void); + void Blur(int x1, int y1, int x2, int y2); + int negpo(void); + int random(int num); + bool CanAdd(int x1, int y1, int x2, int y2); + bool IsWall(int x, int y, int &dx, int &dy); + void Fill(int x1, int y1, int x2, int y2, int val); +}; + +#endif diff --git a/src/medusa.cpp b/src/medusa.cpp new file mode 100644 index 0000000..c503425 --- /dev/null +++ b/src/medusa.cpp @@ -0,0 +1,76 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "medusa.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Medusa::medusa = 0; +ALLEGRO_SAMPLE *Medusa::sound = 0; + +Medusa::Medusa() { + life = 80; + power = 30; + speed = 256; + maxSpeed = speed; + weakness = MAGE; + width = 48; + height = 48; + gold = 2; +} + +Medusa::~Medusa() { +} + +void Medusa::render(double edt) { + if (!medusa) { + medusa = al_load_bitmap("resources/graphics/medusa.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(medusa, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(medusa, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Medusa::getDeathParticles() { + Particle *particle = new Particle(8, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Medusa::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/medusa.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + + diff --git a/src/medusa.h b/src/medusa.h new file mode 100644 index 0000000..a640233 --- /dev/null +++ b/src/medusa.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MEDUSA_H +#define MEDUSA_H + +#include "monster.h" +#include +#include + +class Medusa: public Monster { +public: + static ALLEGRO_BITMAP *medusa; + static ALLEGRO_SAMPLE *sound; + + Medusa(); + ~Medusa(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // MEDUSA_H diff --git a/src/minotaur.cpp b/src/minotaur.cpp new file mode 100644 index 0000000..b2495a6 --- /dev/null +++ b/src/minotaur.cpp @@ -0,0 +1,195 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "minotaur.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Minotaur::minotaur = 0; +ALLEGRO_SAMPLE *Minotaur::sound = 0; + +Minotaur::Minotaur() { + life = 100; + power = 25; + speed = 192; + maxSpeed = speed; + weakness = WARRIOR; + width = 48; + height = 48; + distanceAlert = 360.0; + gold = 2; +} + +Minotaur::~Minotaur() { +} + +void Minotaur::render(double edt) { + if (!minotaur) { + minotaur = al_load_bitmap("resources/graphics/minotaur.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(minotaur, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(minotaur, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Minotaur::getDeathParticles() { + Particle *particle = new Particle(1, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Minotaur:: +artificialIntelligence(double dt, Map *map, std::vector entities) { + if(inercia <= 0) { + int interval = 1 - 0 + 1;//MAX-MIN+1 + int numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + state = numRand; + inercia = 1.0; + if(state == MOVE) { + inercia = 2.0; + interval = 7 - 0 + 1;//MAX-MIN+1 + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDx = dxMoster[numRand]; + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDy = dyMoster[numRand]; + if (stepDx > 0) { + flags = ALLEGRO_FLIP_HORIZONTAL; + } + } + } + + for(unsigned int i = 0; i < entities.size(); i++) { + if(entities[i]->type == PLAYER) { + double distance = position.distanceTo(entities[i]->position) ; + if(distance < distanceAlert && state != CHARGE) { + targetPlayer = ((Player*)entities[i]); + if (targetPlayer->position.getX() > position.getX() - width / 2 && + targetPlayer->position.getX() < position.getX() + width / 2) { + inercia = 2.0; + state = CHARGE; + + if (position.getY() < targetPlayer->position.getY()) { + chargeDirection = Vector2D(0, 1); + } else { + chargeDirection = Vector2D(0, -1); + } + } else if (targetPlayer->position.getY() > position.getY() - height / 2 && + targetPlayer->position.getY() < position.getY() + height / 2) { + inercia = 3.0; + state = CHARGE; + + if (position.getX() < targetPlayer->position.getX()) { + chargeDirection = Vector2D(1, 0); + } else { + chargeDirection = Vector2D(-1, 0); + } + } + } + } + } + + Vector2D curPos; + Vector2D move; + BoundingBox box ; + switch(state) { + case STOP: + inercia-=dt; + break; + + case MOVE: + curPos = position; + move = Vector2D(stepDx,stepDy); + move = move.mult(speed * dt); + position = position.add(Vector2D(move.getX(), 0)); + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0) { + if (move.getX() > 0) { + int dx = (position.getX() + width / 2) - box.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, move.getY())); + box = hasMapCollision(map); + if (box.getMaxY() - box.getMinY() > 0) { + if (move.getY() > 0) { + int dy = (position.getY() + height / 2) - box.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + inercia-=dt; + break; + + case CHARGE: + Vector2D move = chargeDirection.mult(maxSpeed * 1.75 * dt); + + position = position.add(Vector2D(move.getX(), 0)); + BoundingBox box2 = hasMapCollision(map); + if (box2.getMaxX() - box2.getMinX() > 0) { + if (move.getX() > 0) { + int dx = (position.getX() + width / 2) - box2.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box2.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, move.getY())); + box2 = hasMapCollision(map); + if (box2.getMaxY() - box2.getMinY() > 0) { + if (move.getY() > 0) { + int dy = (position.getY() + height / 2) - box2.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box2.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + inercia-=dt; + break; + + } +} + +void Minotaur::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/minotaur.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/minotaur.h b/src/minotaur.h new file mode 100644 index 0000000..19a8060 --- /dev/null +++ b/src/minotaur.h @@ -0,0 +1,40 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MINOTAUR_H +#define MINOTAUR_H + +#include "monster.h" +#include +#include + +class Minotaur : public Monster { +public: + static ALLEGRO_BITMAP *minotaur; + static ALLEGRO_SAMPLE *sound; + Vector2D chargeDirection; + + Minotaur(); + ~Minotaur(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void artificialIntelligence(double dt, Map *map, std::vector entities); + void playSound(); +}; + +#endif // MINOTAUR_H diff --git a/src/monster.cpp b/src/monster.cpp new file mode 100644 index 0000000..39288d3 --- /dev/null +++ b/src/monster.cpp @@ -0,0 +1,204 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "monster.h" +#include "window.h" + +ALLEGRO_BITMAP *Monster::weaknessImg = 0; + +Monster::Monster() { + distanceAlert = 200.0; + distanceAttack = 36.0; + inercia = 0; + type = MONSTER; + width = 48; + height = 48; + immunity = 0.0; + flags = 0; + slowDuration = 0.0; +} + +Monster::~Monster() { +} + +void Monster::collisionWith(Entity *entity) { + if (entity->type == PLAYER) { + Player *player = (Player *) entity; + if (player->immunity <= 0.0) { + player->playHurtSound(); + player->life -= power; + if (player->life < 0.0) { + player->life = 0.0; + } + player->immunity = 1.0; + } + } +} + +void Monster:: +artificialIntelligence(double dt, Map *map, std::vector entities) { + if(inercia <= 0) { + int interval = 1 - 0 + 1;//MAX-MIN+1 + int numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + state = numRand; + inercia = 1.0; + if(state == MOVE) { + inercia = 2.0; + interval = 7 - 0 + 1;//MAX-MIN+1 + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDx = dxMoster[numRand]; + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDy = dyMoster[numRand]; + if (stepDx > 0) { + flags = ALLEGRO_FLIP_HORIZONTAL; + } + } + } + + for(unsigned int i = 0; i < entities.size(); i++) { + if(entities[i]->type == PLAYER) { + double distance = position.distanceTo(entities[i]->position) ; + if(distance < distanceAlert) { + + inercia = 0; + state = FOLLOW_PLAYER; + targetPlayer = ((Player*)entities[i]); + if(distance < distanceAttack) { + state = ATTACK; + } + } + } + } + + Vector2D curPos; + Vector2D move; + BoundingBox box ; + switch(state) { + case STOP: + inercia-=dt; + break; + + case MOVE: + curPos = position; + move = Vector2D(stepDx,stepDy); + move = move.mult(speed * dt); + position = position.add(Vector2D(move.getX(), 0)); + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0) { + if (move.getX() > 0) { + int dx = (position.getX() + width / 2) - box.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, move.getY())); + box = hasMapCollision(map); + if (box.getMaxY() - box.getMinY() > 0) { + if (move.getY() > 0) { + int dy = (position.getY() + height / 2) - box.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + inercia-=dt; + break; + + case FOLLOW_PLAYER: + Vector2D aux = position.mult(-1); + Vector2D movTarget = targetPlayer->position.add(aux); + movTarget = movTarget.normalize(); + movTarget = movTarget.mult(speed * dt); + + position = position.add(Vector2D(movTarget.getX(), 0)); + BoundingBox box2 = hasMapCollision(map); + if (box2.getMaxX() - box2.getMinX() > 0) { + if (movTarget.getX() > 0) { + int dx = (position.getX() + width / 2) - box2.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box2.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, movTarget.getY())); + box2 = hasMapCollision(map); + if (box2.getMaxY() - box2.getMinY() > 0) { + if (movTarget.getY() > 0) { + int dy = (position.getY() + height / 2) - box2.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box2.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + break; + + } +} + +void Monster::update(double dt, Map *map, std::vector entities) { + immunity -= dt; + if (immunity < 0.0) { + immunity = 0.0; + } + + speed = maxSpeed; + if (slowDuration > 0.0) { + slowDuration -= dt; + if (slowDuration <= 0.0) { + slowDuration = 0.0; + } + + speed = 0.5 * maxSpeed; + } + + artificialIntelligence(dt,map,entities); + + Entity *entity = hasEntityCollision(entities); + if (entity) { + collisionWith(entity); + } +} + +bool Monster::isDead() { + return (life <= 0); +} + +void Monster::renderWeakness() { + if (!weaknessImg) { + weaknessImg = al_load_bitmap("resources/graphics/weakness.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + if (weakness == ALL) { + al_draw_tinted_scaled_bitmap(weaknessImg, al_map_rgba_f(1.0, 1.0, 1.0, 1.0), + 0, 0, 48, 16, + windowPos.getX() - 24, windowPos.getY() - height, 48, 16, 0); + } else { + al_draw_tinted_scaled_bitmap(weaknessImg, al_map_rgba_f(1.0, 1.0, 1.0, 1.0), + weakness * 16, 0, 16, 16, + windowPos.getX() - 8, windowPos.getY() - height, 16, 16, 0); + } +} diff --git a/src/monster.h b/src/monster.h new file mode 100644 index 0000000..684403b --- /dev/null +++ b/src/monster.h @@ -0,0 +1,83 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MONSTER_H +#define MONSTER_H + +#include "entity.h" +#include "map.h" +#include "player.h" +#include "particle-system.h" +#include + +#define STOP 0 +#define MOVE 1 +#define FOLLOW_PLAYER 2 +#define ATTACK 3 +#define CHARGE 4 + +#define SPIDER 0 +#define BAT 1 +#define MINOTAUR 2 +#define CONSTRUCT 3 +#define WITCH 4 +#define ZOMBIE 5 +#define MEDUSA 6 +#define GOBLIN 7 +#define GHOST 8 + +const int dxMoster[] = {-1,-1,-1,0,1,1,1,0}; +const int dyMoster[] = {1,0,-1,-1,-1,0,1,1}; + +class Monster : public Entity +{ +public: + static ALLEGRO_BITMAP *weaknessImg; + + Monster(); + ~Monster(); + + int life; + int power; + int maxSpeed; + int speed; + int gold; + Player* targetPlayer; + + int stepDx, stepDy; + + double distanceAlert; + double distanceAttack; + + double slowDuration; + + double inercia; + double immunity; + + PlayerType weakness; + + int state; + + void collisionWith(Entity *entity); + void update(double dt, Map *map, std::vector entities); + virtual void artificialIntelligence(double dt, Map *map, std::vector entities); + bool isDead(); + void renderWeakness(); + virtual void playSound() = 0; +}; + +#endif // MONSTER_H diff --git a/src/particle-system.cpp b/src/particle-system.cpp new file mode 100644 index 0000000..c9c5332 --- /dev/null +++ b/src/particle-system.cpp @@ -0,0 +1,152 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "particle-system.h" +#include "particle.h" +#include "entity.h" + +ParticleSystem::ParticleSystem(Particle *particle, GeneratorType type, Vector2D anchor, double speed, double accel, double lifetime) { + this->particle = particle; + this->type = type; + time = 0; + interval = 0; + this->lifetime = lifetime; + this->anchor = anchor; + this->entity = 0; + this->speed = speed; + this->accel = accel; +} + +ParticleSystem::ParticleSystem(Particle *particle, GeneratorType type, Entity *entity, double speed, double accel, double lifetime) { + this->particle = particle; + this->type = type; + time = 0; + interval = 0; + this->lifetime = lifetime; + this->anchor = Vector2D(entity->position); + this->entity = entity; + this->speed = speed; + this->accel = accel; +} + +ParticleSystem::~ParticleSystem() { +} + +void ParticleSystem::update(double dt) { + time += dt; + interval += dt; + if (interval > particle->interval && time < lifetime) { + interval -= particle->interval; + Particle *newParticle = particle->clone(); + if (type == RADIAL_ACCEL_OUT) { + Vector2D direction = Vector2D((rand() % 100) - 50, (rand() % 100) - 50); + direction = direction.normalize(); + + if (entity) { + newParticle->anchor = Vector2D(entity->position); + } else { + newParticle->anchor = anchor; + } + newParticle->pos = newParticle->anchor; + newParticle->vel = direction.mult(speed); + newParticle->acc = direction.mult(accel); + newParticle->rotation = 2.5; + } else if (type == RADIAL_ACCEL_IN) { + Vector2D direction = Vector2D((rand() % 100) - 50, (rand() % 100) - 50); + direction = direction.normalize(); + + if (entity) { + newParticle->anchor = Vector2D(entity->position); + } else { + newParticle->anchor = anchor; + } + newParticle->pos = newParticle->anchor; + newParticle->pos = newParticle->pos.add(direction.mult(64.0)); + direction = direction.mult(-1.0); + newParticle->vel = direction.mult(speed); + newParticle->acc = direction.mult(accel); + newParticle->rotation = 2.5; + } else if (type == UP_CONSTANT) { + Vector2D direction = Vector2D(0, -1); + Vector2D randPos = Vector2D((rand() % 40) - 20, (rand() % 40) - 20); + + if (entity) { + newParticle->anchor = Vector2D(entity->position); + } else { + newParticle->anchor = anchor; + } + newParticle->pos = newParticle->anchor.add(randPos); + newParticle->vel = direction.mult(speed); + newParticle->acc = direction.mult(accel); + newParticle->rotation = 2.5; + } else if (type == UP_ACCEL) { + Vector2D direction = Vector2D(0, -1); + Vector2D randPos = Vector2D((rand() % 40) - 20, (rand() % 40) - 20); + + if (entity) { + newParticle->anchor = Vector2D(entity->position); + } else { + newParticle->anchor = anchor; + } + newParticle->pos = newParticle->anchor.add(randPos); + newParticle->vel = direction.mult(speed); + newParticle->acc = direction.mult(accel); + newParticle->rotation = 0.0; + newParticle->radians = 0.0; + } else if (type == DOWN_BRAKE) { + Vector2D direction = Vector2D(0, 1); + Vector2D randPos = Vector2D((rand() % 40) - 20, (rand() % 40) - 20); + + if (entity) { + newParticle->anchor = Vector2D(entity->position); + } else { + newParticle->anchor = anchor; + } + newParticle->pos = newParticle->anchor.add(randPos); + newParticle->pos = newParticle->pos.add(Vector2D(0, -32)); + newParticle->vel = direction.mult(speed); + newParticle->acc = direction.mult(accel); + newParticle->rotation = 0.0; + newParticle->radians = 0.0; + } + particles.push_back(newParticle); + } + if (time > lifetime) { + time = lifetime; + } + + std::vector::iterator it = particles.begin(); + while (it != particles.end()) { + Particle *uParticle = (*it); + if (uParticle->isDead()) { + it = particles.erase(it); + } else { + uParticle->update(dt); + it++; + } + } +} + +void ParticleSystem::render(double dt) { + for (unsigned int i = 0; i < particles.size(); i++) { + particles[i]->render(dt); + } +} + +bool ParticleSystem::isDead() { + return (time >= lifetime) && particles.empty(); +} diff --git a/src/particle-system.h b/src/particle-system.h new file mode 100644 index 0000000..fb15925 --- /dev/null +++ b/src/particle-system.h @@ -0,0 +1,56 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef PARTICLESYSTEM_H +#define PARTICLESYSTEM_H + +#include "particle.h" +#include + +class Entity; + +enum GeneratorType { + RADIAL_ACCEL_OUT, + RADIAL_ACCEL_IN, + UP_CONSTANT, + UP_ACCEL, + DOWN_BRAKE +}; + +class ParticleSystem { +public: + ParticleSystem(Particle *particle, GeneratorType type, Vector2D anchor, double speed, double accel, double lifetime); + ParticleSystem(Particle *particle, GeneratorType type, Entity *entity, double speed, double accel, double lifetime); + ~ParticleSystem(); + + GeneratorType type; + double time; + double lifetime; + double interval; + Entity *entity; + Vector2D anchor; + double speed; + double accel; + Particle *particle; + std::vector particles; + + void update(double dt); + void render(double dt); + bool isDead(); +}; + +#endif // PARTICLESYSTEM_H diff --git a/src/particle.cpp b/src/particle.cpp new file mode 100644 index 0000000..7e65024 --- /dev/null +++ b/src/particle.cpp @@ -0,0 +1,81 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "particle.h" +#include "window.h" + +ALLEGRO_BITMAP *Particle::particles = 0; + +Particle::Particle(int id, int width, int height, double interval, double startOpacity, double endOpacity, double lifetime) { + this->id = id; + this->width = width; + this->height = height; + this->anchor = anchor; + this->interval = interval; + this->pos = anchor; + this->vel = vel; + this->acc = acc; + this->rotation = 0.0; + this->radians = (((double)(rand() % 360)) / 360.0) * 6.28; + this->startOpacity = startOpacity; + this->endOpacity = endOpacity; + this->lifetime = lifetime; + this->time = 0; +} + +Particle::~Particle() { + +} + +void Particle::update(double dt) { + vel = vel.add(acc.mult(dt)); + pos = pos.add(vel.mult(dt)); + time += dt; + if (time > lifetime) { + time = lifetime; + } + radians += rotation * dt; +} + +void Particle::render(double dt) { + if (!particles) { + particles = al_load_bitmap("resources/graphics/particles.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(pos); + + double t = time / lifetime; + double opacity = (1 - t) * startOpacity + t * endOpacity; + ALLEGRO_COLOR color = al_map_rgba(255, 255, 255, (opacity * 255)); + + al_draw_tinted_scaled_rotated_bitmap_region(particles, 0, id * height, width, height, color, + width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 2.0, 2.0, radians, 0); +} + +bool Particle::isDead() { + return (time >= lifetime); +} + +Particle *Particle::clone() { + Particle *particle = new Particle(id, width, height, interval, startOpacity, endOpacity, lifetime); + return particle; +} + + + diff --git a/src/particle.h b/src/particle.h new file mode 100644 index 0000000..3d6df2c --- /dev/null +++ b/src/particle.h @@ -0,0 +1,55 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef PARTICLE_H +#define PARTICLE_H + +#include "vector2d.h" +#include + +class Particle { +public: + Particle(int id, int width, int height, double interval, double startOpacity, double endOpacity, double lifetime); + ~Particle(); + + static ALLEGRO_BITMAP *particles; + + int id; + int width; + int height; + + Vector2D anchor; + double interval; + + Vector2D pos; + Vector2D vel; + Vector2D acc; + double rotation; + double radians; + + double startOpacity; + double endOpacity; + double lifetime; + double time; + + void update(double dt); + void render(double dt); + bool isDead(); + Particle *clone(); +}; + +#endif // PARTICLE_H diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..d6253ac --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,374 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "player.h" +#include "map.h" +#include "warrior.h" +#include "item.h" +#include "potion.h" +#include "potion-change.h" +#include "potion-haste.h" +#include "potion-slow.h" +#include "sword.h" +#include "amulet.h" +#include "potion-poison.h" +#include "boots.h" +#include "monster.h" +#include "window.h" + +ALLEGRO_SAMPLE *Player::missSound = 0; +ALLEGRO_SAMPLE *Player::hurtSound = 0; +ALLEGRO_SAMPLE *Player::swordSound = 0; +ALLEGRO_SAMPLE *Player::daggerSound = 0; +ALLEGRO_SAMPLE *Player::fireballSound = 0; + +Player::Player() { + width = 48; + height = 48; + orientation = FACING_UP; + attackCooldown = 0.0; + projectile = 0; + for (int i = 0; i < 6; i++) { + slots[i] = EMPTY; + items[i] = 0; + } + maxSlots = 1; + type = PLAYER; + immunity = 0.0; + flags = 0; + gold = 0; + usedItem = 0; + + keyz[KEY_UP] = false; + keyz[KEY_DOWN] = false; + keyz[KEY_LEFT] = false; + keyz[KEY_RIGHT] = false; +} + +Player::~Player() { + +} + +void Player::inputEvent(InputEvent event, Map *map, std::vector entities, Player **player) { + switch(event) { + case UP_PRESS: + if (!keyz[KEY_UP]) { + keyz[KEY_UP] = true; + velocity = velocity.add(Vector2D(0, -1)); + } + break; + + case UP_RELEASE: + if (keyz[KEY_UP]) { + keyz[KEY_UP] = false; + velocity = velocity.add(Vector2D(0, 1)); + } + break; + + case DOWN_PRESS: + if (!keyz[KEY_DOWN]) { + keyz[KEY_DOWN] = true; + velocity = velocity.add(Vector2D(0, 1)); + } + break; + + case DOWN_RELEASE: + if (keyz[KEY_DOWN]) { + keyz[KEY_DOWN] = false; + velocity = velocity.add(Vector2D(0, -1)); + } + break; + + case LEFT_PRESS: + if (!keyz[KEY_LEFT]) { + keyz[KEY_LEFT] = true; + velocity = velocity.add(Vector2D(-1, 0)); + } + break; + + case LEFT_RELEASE: + if (keyz[KEY_LEFT]) { + keyz[KEY_LEFT] = false; + velocity = velocity.add(Vector2D(1, 0)); + } + break; + + case RIGHT_PRESS: + if (!keyz[KEY_RIGHT]) { + keyz[KEY_RIGHT] = true; + velocity = velocity.add(Vector2D(1, 0)); + } + break; + + case RIGHT_RELEASE: + if (keyz[KEY_RIGHT]) { + keyz[KEY_RIGHT] = false; + velocity = velocity.add(Vector2D(-1, 0)); + } + break; + + case BUT1_PRESS: + if (attackCooldown <= 0.0) { + prepareAttack(); + } + break; + + case BUT1_RELEASE: + break; + + case BUT2_PRESS: + if(this->slots[0] != EMPTY) { + Item *it; + switch(this->slots[0]) { + case POTION_LIFE: + it = new PotionLife(); + break; + case POTION_POISON: + it = new PotionPoison(); + break; + case POTION_SLOW: + it = new PotionSlow(); + break; + case POTION_HASTE: + it = new PotionHaste(); + break; + case POTION_SWAP: + it = new PotionChange(); + break; + case BOOTS_OF_SPEED: + it = new Boots(); + break; + case AMULET: + it = new Amulet(); + break; + case HELMET: + it = new Sword(); + break; + } + it->action(map,entities,player,this); + this->slots[0] = EMPTY; + this->items[0] = 0; + usedItem = it; + usedItem->playUseSound(); + } + break; + + case BUT2_RELEASE: + break; + + case BUT3_PRESS: + if(maxSlots > 1) { + if(this->slots[1] != EMPTY) { + Item *it; + switch(this->slots[1]) { + case POTION_LIFE: + it = new PotionLife(); + break; + case POTION_POISON: + it = new PotionPoison(); + break; + case POTION_SLOW: + it = new PotionSlow(); + break; + case POTION_HASTE: + it = new PotionHaste(); + break; + case POTION_SWAP: + it = new PotionChange(); + break; + case BOOTS_OF_SPEED: + it = new Boots(); + break; + case AMULET: + it = new Amulet(); + break; + case HELMET: + it = new Sword(); + break; + } + it->action(map,entities,player,this); + this->slots[1] = EMPTY; + this->items[1] = 0; + usedItem = it; + usedItem->playUseSound(); + } + + } + break; + + case BUT3_RELEASE: + break; + + case BUT4_PRESS: + break; + + case BUT4_RELEASE: + break; + + case BUT5_PRESS: + break; + + case BUT5_RELEASE: + break; + + case BUT6_PRESS: + break; + + case BUT6_RELEASE: + break; + } + + if (keyz[KEY_UP] && !keyz[KEY_DOWN] && !keyz[KEY_LEFT] && !keyz[KEY_RIGHT]) { + orientation = FACING_UP; + } + if (!keyz[KEY_UP] && keyz[KEY_DOWN] && !keyz[KEY_LEFT] && !keyz[KEY_RIGHT]) { + orientation = FACING_DOWN; + } + if (!keyz[KEY_UP] && !keyz[KEY_DOWN] && keyz[KEY_LEFT] && !keyz[KEY_RIGHT]) { + orientation = FACING_LEFT; + flags = 0; + } + if (!keyz[KEY_UP] && !keyz[KEY_DOWN] && !keyz[KEY_LEFT] && keyz[KEY_RIGHT]) { + orientation = FACING_RIGHT; + flags = ALLEGRO_FLIP_HORIZONTAL; + } +} + +Entity *Player::handleCollisions(std::vector entities) { + Entity *result = 0; + BoundingBox box = BoundingBox(position.getX() - width / 2, + position.getY() - height / 2, + width, height); + + // colisão com entidades + for (unsigned int i = 0; i < entities.size(); i++) { + BoundingBox entityBox = BoundingBox(entities[i]->position.getX() - entities[i]->width / 2, + entities[i]->position.getY() - entities[i]->height / 2, + entities[i]->width, entities[i]->height); + if (box.intersects(entityBox)) { + collisionWith(entities[i]); + } + } + + return result; +} + +BoundingBox Player::hasMapCollision(Map *map) { + BoundingBox result = BoundingBox(0, 0, 0, 0); + BoundingBox box = BoundingBox(position.getX() - width / 4, + position.getY() - height / 4, + width / 2, height / 2); + + int tileX = position.getX() / TILESET_WIDTH; + int tileY = position.getY() / TILESET_HEIGHT; + + // colisão com o mapa + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int x = tileX + dx; + int y = tileY + dy; + if (map->tiles[y][x] == WALL) { + BoundingBox tileBox = BoundingBox(x * TILESET_WIDTH, y * TILESET_HEIGHT, + TILESET_WIDTH, TILESET_HEIGHT); + if (box.intersects(tileBox)) { + result = tileBox; + return result; + } + } + } + } + + return result; +} + +void Player::update(double dts, Map *map, std::vector entities) { + lifeBar -= 50.0 * dts; + if (lifeBar < life) { + lifeBar = life; + } + + immunity -= dts; + if (immunity <= 0.0) { + immunity = 0.0; + } + + Vector2D vel = Vector2D(velocity); + vel = vel.mult(speed * dts); + + Vector2D curPos = position; + position = position.add(Vector2D(vel.getX(), 0)); + BoundingBox box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0) { + if (vel.getX() > 0) { + int dx = (position.getX() + width / 4) - box.getMinX(); + position.setX(position.getX() - dx - 1); + } else if (vel.getX() < 0) { + int dx = box.getMaxX() - (position.getX() - width / 4); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, vel.getY())); + box = hasMapCollision(map); + if (box.getMaxY() - box.getMinY() > 0) { + if (vel.getY() > 0) { + int dy = (position.getY() + height / 4) - box.getMinY(); + position.setY(position.getY() - dy - 1); + } else if (vel.getY() < 0) { + int dy = box.getMaxY() - (position.getY() - height / 4); + position.setY(position.getY() + dy + 1); + } + } + + handleCollisions(entities); + + if (attackCooldown > 0.0) { + attackCooldown -= dts; + if (attackCooldown <= 0.0) { + attackCooldown = 0.0; + } + } +} + +void Player::renderWeakness() { + if (!Monster::weaknessImg) { + Monster::weaknessImg = al_load_bitmap("resources/graphics/weakness.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Monster::weaknessImg, al_map_rgba_f(1.0, 1.0, 1.0, 1.0), + playerType * 16, 0, 16, 16, + windowPos.getX() - 8, windowPos.getY() - height, 16, 16, 0); +} + +void Player::playMissSound() { + if (!missSound) { + missSound = al_load_sample("resources/sound/miss.wav"); + } + + al_play_sample(missSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + +void Player::playHurtSound() { + if (!hurtSound) { + hurtSound = al_load_sample("resources/sound/hurt.wav"); + } + + al_play_sample(hurtSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..2e8bf12 --- /dev/null +++ b/src/player.h @@ -0,0 +1,85 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef PLAYER_H +#define PLAYER_H + +#include "entity.h" +#include +#include + +class Item; + +enum PlayerType { + ALL = -1, WARRIOR = 0, MAGE = 1, ROGUE = 2 +}; + +enum InputEvent { + UP_PRESS, UP_RELEASE, DOWN_PRESS, DOWN_RELEASE, + LEFT_PRESS, LEFT_RELEASE, RIGHT_PRESS, RIGHT_RELEASE, + BUT1_PRESS, BUT1_RELEASE, BUT2_PRESS, BUT2_RELEASE, + BUT3_PRESS, BUT3_RELEASE, BUT4_PRESS, BUT4_RELEASE, + BUT5_PRESS, BUT5_RELEASE, BUT6_PRESS, BUT6_RELEASE +}; + +enum { + KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT +}; + +class Player : public Entity { +public: + static ALLEGRO_SAMPLE *missSound; + static ALLEGRO_SAMPLE *hurtSound; + static ALLEGRO_SAMPLE *swordSound; + static ALLEGRO_SAMPLE *daggerSound; + static ALLEGRO_SAMPLE *fireballSound; + + Player(); + ~Player(); + + int life; + double lifeBar; + int power; + int speed; + int maxSlots; + int slots[6]; + Item *items[6]; + int playerType; + double immunity; + bool keyz[4]; + int maxLife; + int gold; + + Entity *projectile; + Item *usedItem; + + bool isAttacking; + double attackCooldown; + + virtual std::string getName() = 0; + void inputEvent(InputEvent event, Map *map, std::vector entities, Player **player); + void update(double dts, Map *map, std::vector entities); + virtual void prepareAttack() = 0; + Entity *handleCollisions(std::vector entities); + BoundingBox hasMapCollision(Map *map); + void renderWeakness(); + virtual void renderScreen(int x, int y) = 0; + void playMissSound(); + void playHurtSound(); +}; + +#endif // PLAYER_H diff --git a/src/potion-change.cpp b/src/potion-change.cpp new file mode 100644 index 0000000..f68cafc --- /dev/null +++ b/src/potion-change.cpp @@ -0,0 +1,66 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "potion-change.h" +#include "item.h" +#include "window.h" +#include +#include + +PotionChange::PotionChange():Item(POTION_SWAP) { +} + +PotionChange::~PotionChange() { +} + +void PotionChange::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void PotionChange::action( Map *map, std::vector entities, Player **player, Player* eu) { + bool keyz[4]; + Vector2D velocity; + + velocity = Vector2D(player[0]->velocity); + keyz[KEY_UP] = player[0]->keyz[KEY_UP]; + keyz[KEY_DOWN] = player[0]->keyz[KEY_DOWN]; + keyz[KEY_LEFT] = player[0]->keyz[KEY_LEFT]; + keyz[KEY_RIGHT] = player[0]->keyz[KEY_RIGHT]; + player[0]->velocity = player[1]->velocity; + player[0]->keyz[KEY_UP] = player[1]->keyz[KEY_UP]; + player[0]->keyz[KEY_DOWN] = player[1]->keyz[KEY_DOWN]; + player[0]->keyz[KEY_LEFT] = player[1]->keyz[KEY_LEFT]; + player[0]->keyz[KEY_RIGHT] = player[1]->keyz[KEY_RIGHT]; + player[1]->velocity = velocity; + player[1]->keyz[KEY_UP] = keyz[KEY_UP]; + player[1]->keyz[KEY_DOWN] = keyz[KEY_DOWN]; + player[1]->keyz[KEY_LEFT] = keyz[KEY_LEFT]; + player[1]->keyz[KEY_RIGHT] = keyz[KEY_RIGHT]; + + Player *p = player[0]; + player[0]=player[1]; + player[1] = p; +} diff --git a/src/potion-change.h b/src/potion-change.h new file mode 100644 index 0000000..c378551 --- /dev/null +++ b/src/potion-change.h @@ -0,0 +1,33 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef POTIONCHANGE_H +#define POTIONCHANGE_H + +#include "item.h" +#include + +class PotionChange: public Item +{ +public: + PotionChange(); + ~PotionChange(); + void render(double edt); + void action( Map *map, std::vector entities, Player **player, Player* eu); +}; + +#endif // POTIONCHANGE_H diff --git a/src/potion-haste.cpp b/src/potion-haste.cpp new file mode 100644 index 0000000..5ee07c5 --- /dev/null +++ b/src/potion-haste.cpp @@ -0,0 +1,69 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "potion-haste.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *PotionHaste::sound = 0; + +PotionHaste::PotionHaste():Item(POTION_HASTE) { +} + +PotionHaste::~PotionHaste() { +} + +void PotionHaste::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void PotionHaste::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player* use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + target = use; + + use->speed += 10; +} + +ParticleSystem *PotionHaste::getUseParticles() { + Particle *particle = new Particle(15, 32, 32, 0.03, 1.0, 0.0, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, UP_ACCEL, target, 160, 100, 0.3); + + return particleSystem; +} + +void PotionHaste::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/haste.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/potion-haste.h b/src/potion-haste.h new file mode 100644 index 0000000..6423787 --- /dev/null +++ b/src/potion-haste.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef POTIONHASTE_H +#define POTIONHASTE_H + +#include "item.h" +#include +#include + +class PotionHaste : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + PotionHaste(); + ~PotionHaste(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // POTIONHASTE_H diff --git a/src/potion-poison.cpp b/src/potion-poison.cpp new file mode 100644 index 0000000..2c2a911 --- /dev/null +++ b/src/potion-poison.cpp @@ -0,0 +1,77 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "potion-poison.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *PotionPoison::sound = 0; + +PotionPoison::PotionPoison():Item(POTION_POISON) { +} + +PotionPoison::~PotionPoison() { +} + +void PotionPoison::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void PotionPoison::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player* use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + target = use; + + use->playHurtSound(); + use->immunity = 1.0; + + if(use->life - 10 >= 0 ) { + use->life -= 10; + + } else { + use->life = 0; + } +} + +ParticleSystem *PotionPoison::getUseParticles() { + Particle *particle = new Particle(14, 32, 32, 0.03, 1.0, 0.3, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, UP_CONSTANT, target, 120, 0, 0.4); + + return particleSystem; +} + +void PotionPoison::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/poison.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/potion-poison.h b/src/potion-poison.h new file mode 100644 index 0000000..8d89fab --- /dev/null +++ b/src/potion-poison.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef POTIONPOISON_H +#define POTIONPOISON_H + +#include "item.h" +#include +#include + +class PotionPoison : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + PotionPoison(); + ~PotionPoison(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // POTIONPOISON_H diff --git a/src/potion-slow.cpp b/src/potion-slow.cpp new file mode 100644 index 0000000..9377dab --- /dev/null +++ b/src/potion-slow.cpp @@ -0,0 +1,69 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "potion-slow.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *PotionSlow::sound = 0; + +PotionSlow::PotionSlow():Item(POTION_SLOW) { +} + +PotionSlow::~PotionSlow() { +} + +void PotionSlow::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void PotionSlow::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player* use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + target = use; + + use->speed -= 10; +} + +ParticleSystem *PotionSlow::getUseParticles() { + Particle *particle = new Particle(16, 32, 32, 0.03, 1.0, 0.0, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, DOWN_BRAKE, target, 160, 100, 0.3); + + return particleSystem; +} + +void PotionSlow::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/slow.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/potion-slow.h b/src/potion-slow.h new file mode 100644 index 0000000..21e1bb0 --- /dev/null +++ b/src/potion-slow.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef POTIONSLOW_H +#define POTIONSLOW_H + +#include "item.h" +#include +#include + +class PotionSlow : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + PotionSlow(); + ~PotionSlow(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // POTIONSLOW_H diff --git a/src/potion.cpp b/src/potion.cpp new file mode 100644 index 0000000..8f97180 --- /dev/null +++ b/src/potion.cpp @@ -0,0 +1,74 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "potion.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *PotionLife::sound = 0; + +PotionLife::PotionLife():Item(POTION_LIFE) { +} + +PotionLife::~PotionLife() { +} + +void PotionLife::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void PotionLife::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player* use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + target = use; + + if(use->life+ 10 <= use->maxLife) { + use->life += 10; + + } else { + use->life= use->maxLife; + } +} + +ParticleSystem *PotionLife::getUseParticles() { + Particle *particle = new Particle(13, 32, 32, 0.015, 1.0, 0.3, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, UP_CONSTANT, target, 160, 0, 0.2); + + return particleSystem; +} + +void PotionLife::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/heal.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/potion.h b/src/potion.h new file mode 100644 index 0000000..b203f8c --- /dev/null +++ b/src/potion.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef POTION_H +#define POTION_H + +#include "item.h" +#include +#include + +class PotionLife : public Item +{ +public: + static ALLEGRO_SAMPLE *sound; + + PotionLife(); + ~PotionLife(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // POTION_H diff --git a/src/rogue.cpp b/src/rogue.cpp new file mode 100644 index 0000000..48cbca3 --- /dev/null +++ b/src/rogue.cpp @@ -0,0 +1,92 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "rogue.h" +#include "window.h" +#include "dagger.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Rogue::rogue = 0; + +Rogue::Rogue() { + life = 80; + lifeBar = life; + maxLife = life; + power = 20; + speed = 330; + + maxSlots = 2; + attackTime = 0.0; + isAttacking = false; + + playerType = ROGUE; +} + +Rogue::~Rogue() { + +} + +std::string Rogue::getName() { + return "Rogue"; +} + +void Rogue::collisionWith(Entity *entity) { + +} + +void Rogue::render(double edt) { + if (!rogue) { + rogue = al_load_bitmap("resources/graphics/rogue.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(rogue, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(rogue, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +void Rogue::renderScreen(int x, int y) { + if (!rogue) { + rogue = al_load_bitmap("resources/graphics/rogue.png"); + } + + al_draw_tinted_scaled_bitmap(rogue, al_map_rgb(255, 255, 255), + 0, 0, width, height, + x, y, width, height, 0); +} + +void Rogue::prepareAttack() { + attackCooldown = DAGGER_COOLDOWN; + projectile = new Dagger(this, orientation, power); + + if (!Player::daggerSound) { + Player::daggerSound = al_load_sample("resources/sound/dagger.wav"); + } + + al_play_sample(Player::daggerSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/rogue.h b/src/rogue.h new file mode 100644 index 0000000..1476707 --- /dev/null +++ b/src/rogue.h @@ -0,0 +1,41 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef ROGUE_H +#define ROGUE_H + +#include "player.h" +#include + +const double DAGGER_COOLDOWN = 0.15; + +class Rogue : public Player { +public: + static ALLEGRO_BITMAP *rogue; + double attackTime; + + Rogue(); + ~Rogue(); + + std::string getName(); + void collisionWith(Entity *entity); + void render(double edt); + void prepareAttack(); + void renderScreen(int x, int y); +}; + +#endif // ROGUE_H diff --git a/src/spider.cpp b/src/spider.cpp new file mode 100644 index 0000000..658138e --- /dev/null +++ b/src/spider.cpp @@ -0,0 +1,76 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "spider.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Spider::spider = 0; +ALLEGRO_SAMPLE *Spider::sound = 0; + +Spider::Spider() { + life = 20; + power = 15; + speed = 320; + maxSpeed = speed; + weakness = ROGUE; + width = 48; + height = 48; + gold = 2; +} + +Spider::~Spider() { +} + +void Spider::render(double edt) { + if (!spider) { + spider = al_load_bitmap("resources/graphics/spider.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(spider, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(spider, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Spider::getDeathParticles() { + Particle *particle = new Particle(6, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Spider::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/spider.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + + diff --git a/src/spider.h b/src/spider.h new file mode 100644 index 0000000..cc851a8 --- /dev/null +++ b/src/spider.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef SPIDER_H +#define SPIDER_H + +#include "monster.h" +#include +#include + +class Spider : public Monster { +public: + static ALLEGRO_BITMAP *spider; + static ALLEGRO_SAMPLE *sound; + + Spider(); + ~Spider(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // SPIDER_H diff --git a/src/sword-swing.cpp b/src/sword-swing.cpp new file mode 100644 index 0000000..3fd72f2 --- /dev/null +++ b/src/sword-swing.cpp @@ -0,0 +1,156 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "sword-swing.h" +#include "warrior.h" +#include "window.h" +#include "monster.h" +#include + +SwordSwing::SwordSwing(Player *player, Orientation orientation, int damage) { + type = PROJECTILE; + this->player = player; + this->orientation = orientation; + + width = 48; + height = 48; + this->damage = damage; + attackTime = 0.0; +} + +SwordSwing::~SwordSwing() { + +} + +void SwordSwing::collisionWith(Entity *entity) { + if (entity->type == MONSTER) { + Monster *monster = (Monster *)entity; + monster->slowDuration = 1.0; + if (monster->weakness == ALL || monster->weakness == player->playerType) { + if (monster->immunity <= 0.0) { + monster->playSound(); + monster->life -= damage; + if (monster->life < 0.0) { + monster->life = 0.0; + player->gold += monster->gold; + } + monster->immunity = 0.5; + } + } else { + player->playMissSound(); + } + } +} + +void SwordSwing::update(double dt, Map *map, std::vector entities) { + attackTime += dt; + if (attackTime > SWING_DURATION) { + attackTime = SWING_DURATION; + } + + Vector2D swordPos = Vector2D(player->position); + Vector2D direction; + switch (orientation) { + case FACING_UP: + direction = Vector2D(0, -1); + break; + + case FACING_LEFT: + direction = Vector2D(-1, 0); + break; + + case FACING_RIGHT: + direction = Vector2D(1, 0); + break; + + case FACING_DOWN: + flags = ALLEGRO_FLIP_VERTICAL; + direction = Vector2D(0, 1); + break; + } + + double t = attackTime / SWING_DURATION; + double swingStart = 0.0; + double swingEnd = 6.28; + double radians = ((1 - t) * swingStart) + (t * swingEnd); + + Vector2D rotated = Vector2D(direction.getX() * cos(-radians) + direction.getY() * sin(-radians), + -direction.getX() * sin(-radians) + direction.getY() * cos(-radians)); + rotated = rotated.mult(width); + rotated = rotated.add(Vector2D(swordPos)); + + BoundingBox box = BoundingBox(rotated.getX() - width / 2, + rotated.getY() - height / 2, + width, height); + + // colisão com entidades + for (unsigned int i = 0; i < entities.size(); i++) { + if (entities[i]->type == MONSTER) { + BoundingBox entityBox = BoundingBox(entities[i]->position.getX() - entities[i]->width / 2, + entities[i]->position.getY() - entities[i]->height / 2, + entities[i]->width, entities[i]->height); + if (box.intersects(entityBox)) { + Entity *result = entities[i]; + collisionWith(result); + } + } + } +} + +void SwordSwing::render(double edt) { + if (!Warrior::warrior) { + Warrior::warrior = al_load_bitmap("resources/graphics/warrior.png"); + } + + double t = attackTime / SWING_DURATION; + double swingStart = 0; + double swingEnd = 6.28; + double radians = ((1 - t) * swingStart) + (t * swingEnd); + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(player->position); + + switch (orientation) { + case FACING_UP: + al_draw_tinted_scaled_rotated_bitmap_region(Warrior::warrior, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, 3 * height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, radians, 0); + break; + + case FACING_LEFT: + al_draw_tinted_scaled_rotated_bitmap_region(Warrior::warrior, width, height, width, height, al_map_rgb(255, 255, 255), + 3 * width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, radians, 0); + break; + + case FACING_RIGHT: + al_draw_tinted_scaled_rotated_bitmap_region(Warrior::warrior, width, height, width, height, al_map_rgb(255, 255, 255), + - width / 2, height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, radians, ALLEGRO_FLIP_HORIZONTAL); + break; + + case FACING_DOWN: + al_draw_tinted_scaled_rotated_bitmap_region(Warrior::warrior, width, 0, width, height, al_map_rgb(255, 255, 255), + width / 2, - height / 2, + windowPos.getX(), windowPos.getY(), 1.0, 1.0, radians, ALLEGRO_FLIP_VERTICAL); + break; + } +} + +bool SwordSwing::isDead() { + return (attackTime >= SWING_DURATION); +} diff --git a/src/sword-swing.h b/src/sword-swing.h new file mode 100644 index 0000000..b24ce9a --- /dev/null +++ b/src/sword-swing.h @@ -0,0 +1,40 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef SWORDSWING_H +#define SWORDSWING_H + +#include "entity.h" +#include "player.h" + +class SwordSwing : public Entity { +public: + SwordSwing(Player *player, Orientation orientation, int damage); + ~SwordSwing(); + + Player *player; + Orientation orientation; + double attackTime; + int damage; + + void collisionWith(Entity *entity); + void update(double dt, Map *map, std::vector entities); + void render(double edt); + bool isDead(); +}; + +#endif // SWORDSWING_H diff --git a/src/sword.cpp b/src/sword.cpp new file mode 100644 index 0000000..7e2ef9b --- /dev/null +++ b/src/sword.cpp @@ -0,0 +1,70 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "sword.h" +#include "window.h" +#include +#include + +ALLEGRO_SAMPLE *Sword::sound = 0; + +Sword::Sword():Item(HELMET) { +} + +Sword::~Sword() { +} + +void Sword::render(double edt) { + if (!Item::items) { + Item::items = al_load_bitmap("resources/graphics/items.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(Item::items, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); +} + +void Sword::action( Map *map, std::vector entities, Player **player, Player* eu) { + Player *use; + if(eu == player[0]) { + use = player[1]; + } else { + use = player[0]; + } + + use->playerType = WARRIOR; + target = use; +} + +ParticleSystem *Sword::getUseParticles() { + Particle *particle = new Particle(10, 32, 32, 0.03, 1.0, 0.0, 0.4); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_IN, target, 120, 0, 0.3); + + return particleSystem; +} + +void Sword::playUseSound() { + if (!sound) { + sound = al_load_sample("resources/sound/classchange.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + diff --git a/src/sword.h b/src/sword.h new file mode 100644 index 0000000..6ef9d7e --- /dev/null +++ b/src/sword.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef SWORD_H +#define SWORD_H + +#include "item.h" +#include +#include + +class Sword : public Item { +public: + static ALLEGRO_SAMPLE *sound; + + Sword(); + ~Sword(); + + void render(double edt); + void action(Map *map, std::vector entities, Player **player, Player* eu); + ParticleSystem *getUseParticles(); + void playUseSound(); +}; + +#endif // SWORD_H diff --git a/src/title-screen.cpp b/src/title-screen.cpp new file mode 100644 index 0000000..98017d3 --- /dev/null +++ b/src/title-screen.cpp @@ -0,0 +1,139 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "title-screen.h" +#include "fadein.h" +#include "fadeout.h" +#include "window.h" + +namespace Game { + +TitleScreen::TitleScreen() { + jumpToGame = false; + + entryTransition = 0; + exitTransition = 0; + title = 0; + credits = 0; + font = 0; + curTransition = 0; + + player1Ready = false; + player2Ready = false; +} + +TitleScreen::~TitleScreen() { + +} + +void TitleScreen::start(Engine * engine) { + jumpToGame = false; + entryTransition = new Fadein(al_map_rgb(0, 0, 0), 1.0); + exitTransition = new Fadeout(al_map_rgb(0, 0, 0), 1.0); + curTransition = entryTransition; + player1Ready = false; + player2Ready = false; +} + +void TitleScreen::stop(Engine * engine) { + +} + +void TitleScreen::handleEvents(Engine * engine ,ALLEGRO_EVENT *event) { + if (!curTransition) { + if(event->type == ALLEGRO_EVENT_KEY_DOWN) { + switch (event->keyboard.keycode) { + case ALLEGRO_KEY_1: + player1Ready = true; + break; + + case ALLEGRO_KEY_2: + player2Ready = true; + break; + } + + } else if (event->type == ALLEGRO_EVENT_KEY_UP) { + switch (event->keyboard.keycode) { + case ALLEGRO_KEY_1: + player1Ready = false; + break; + + case ALLEGRO_KEY_2: + player2Ready = false; + break; + + case ALLEGRO_KEY_ESCAPE: + engine->endGame = true; + break; + } + } + } +} + +void TitleScreen::update(Engine *engine, double dts) { + if (player1Ready && player2Ready) { + jumpToGame = true; + curTransition = exitTransition; + } + + if (jumpToGame && curTransition) { + if (curTransition->isFinished()) { + engine->jumpScreen(1); + } else { + curTransition->update(dts); + } + } else { + if (curTransition) { + curTransition->update(dts); + if (curTransition->isFinished()) { + curTransition = 0; + } + } + } +} + +void TitleScreen::render(Engine *engine, double edt) { + if (!title) { + title = al_load_bitmap("resources/graphics/title.png"); + credits = al_load_bitmap("resources/graphics/credits.png"); + } + if (!font) { + font = al_load_ttf_font("resources/fonts/segoepr.ttf", 50, 0); + } + al_clear_to_color(al_map_rgb(0,0,0)); + al_draw_bitmap(title, 0, 0, 0); + al_draw_bitmap(credits, 0, Window::getInstance()->getHeight() - (al_get_bitmap_height(credits) + 20), 0); + + char timeStr[50]; + sprintf(timeStr, "Player 1 and Player 2"); + + char timeStr2[50]; + sprintf(timeStr2, "press start together to begin"); + + al_draw_text(font, al_map_rgb(255, 255, 255), (Window::getInstance()->getWidth() / 2), Window::getInstance()->getHeight() - 160, ALLEGRO_ALIGN_CENTRE, timeStr); + al_draw_text(font, al_map_rgb(255, 255, 255), (Window::getInstance()->getWidth() / 2), Window::getInstance()->getHeight() - 100, ALLEGRO_ALIGN_CENTRE, timeStr2); + + if (curTransition) { + curTransition->render(edt); + } +} + +void TitleScreen::flipStateBuffer() { + +} + +} diff --git a/src/title-screen.h b/src/title-screen.h new file mode 100644 index 0000000..7370737 --- /dev/null +++ b/src/title-screen.h @@ -0,0 +1,59 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef TITLESCREEN_H +#define TITLESCREEN_H + +#include "game.h" +#include + +class Environment; +class Transition; + +namespace Game { + +class TitleScreen : public Screen { + private: + ALLEGRO_BITMAP *title; + ALLEGRO_BITMAP *credits; + ALLEGRO_FONT *font; + enum MYKEYS {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT}; + Environment *environment; + bool jumpToGame; + Transition *entryTransition; + Transition *exitTransition; + Transition *curTransition; + bool player1Ready; + bool player2Ready; + + public: + bool key[4]; + + TitleScreen(); + ~TitleScreen(); + + void start(Engine * engine); + void stop(Engine * engine); + + void handleEvents(Engine * engine ,ALLEGRO_EVENT *event); + void update(Engine * engine ,double dts); + void render(Engine * engine ,double edt); + void flipStateBuffer(); +}; + +} +#endif // TITLESCREEN_H diff --git a/src/transition.h b/src/transition.h new file mode 100644 index 0000000..15e39c0 --- /dev/null +++ b/src/transition.h @@ -0,0 +1,30 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _TRANSITION_H +#define _TRANSITION_H + +class Transition { + public: + virtual ~Transition() {}; + + virtual void update(double dt) = 0; + virtual void render(double edt) = 0; + virtual bool isFinished() = 0; +}; + +#endif diff --git a/src/vector2d.cpp b/src/vector2d.cpp new file mode 100644 index 0000000..abc4e51 --- /dev/null +++ b/src/vector2d.cpp @@ -0,0 +1,98 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "vector2d.h" +#include + +Vector2D::Vector2D() { + this->x = 0.0; + this->y = 0.0; +} + +Vector2D::Vector2D(double x, double y) { + this->x = x; + this->y = y; +} + +Vector2D::Vector2D(Vector2D src, Vector2D dest) { + this->x = dest.getX() - src.getX(); + this->y = dest.getY() - src.getY(); +} + +Vector2D::~Vector2D() { + +} + +void Vector2D::setX(double x) { + this->x = x; +} + +double Vector2D::getX() { + return x; +} + +void Vector2D::setY(double y) { + this->y = y; +} + +double Vector2D::getY() { + return y; +} + +Vector2D Vector2D::add(Vector2D vector) { + Vector2D vectorNovo; + vectorNovo.setX(this->x + vector.getX()); + vectorNovo.setY(this->y + vector.getY()); + + return vectorNovo; +} + +Vector2D Vector2D::mult(double scalar) { + Vector2D vector; + vector.setX(this->x * scalar); + vector.setY(this->y * scalar); + + return vector; +} + +double Vector2D::distanceTo(Vector2D vector) { + double sqrdDeltaX = (this->x - vector.getX()) * (this->x - vector.getX()); + double sqrdDeltaY = (this->y - vector.getY()) * (this->y - vector.getY()); + double distance = sqrt(sqrdDeltaX + sqrdDeltaY); + + return distance; +} + +Vector2D Vector2D::normalize() { + Vector2D normalizedVector; + double length = distanceTo(Vector2D()); + if (length > 1.0e-5) { + normalizedVector = Vector2D(this->x / length, this->y / length); + } + return normalizedVector; +} + +bool Vector2D::equals(Vector2D &vector) { + bool result = false; + + if (std::fabs(getX() - vector.getX()) < 1.0e-5 && + std::fabs(getY() - vector.getY()) < 1.0e-5) { + result = true; + } + + return result; +} diff --git a/src/vector2d.h b/src/vector2d.h new file mode 100644 index 0000000..9356d70 --- /dev/null +++ b/src/vector2d.h @@ -0,0 +1,42 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef _VECTOR2D_h +#define _VECTOR2D_h + +class Vector2D { +private: + double x, y; + +public: + Vector2D(); + Vector2D(double x, double y); + Vector2D(Vector2D src, Vector2D dest); + ~Vector2D(); + + void setX(double x); + double getX(); + void setY(double y); + double getY(); + Vector2D add(Vector2D vector); + Vector2D mult(double scalar); + double distanceTo(Vector2D vector); + Vector2D normalize(); + bool equals(Vector2D &vector); +}; + +#endif diff --git a/src/warrior.cpp b/src/warrior.cpp new file mode 100644 index 0000000..fef2189 --- /dev/null +++ b/src/warrior.cpp @@ -0,0 +1,89 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "warrior.h" +#include "window.h" +#include "sword-swing.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Warrior::warrior = 0; + +Warrior::Warrior() { + life = 120; + lifeBar = life; + power = 60; + speed = 310; + maxLife = life; + attackTime = 0.0; + isAttacking = false; + + playerType = WARRIOR; +} + +Warrior::~Warrior() { + +} + +std::string Warrior::getName() { + return "Warrior"; +} + +void Warrior::collisionWith(Entity *entity) { +} + +void Warrior::render(double edt) { + if (!warrior) { + warrior = al_load_bitmap("resources/graphics/warrior.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(warrior, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(warrior, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +void Warrior::renderScreen(int x, int y) { + if (!warrior) { + warrior = al_load_bitmap("resources/graphics/warrior.png"); + } + + al_draw_tinted_scaled_bitmap(warrior, al_map_rgb(255, 255, 255), + 0, 0, width, height, + x, y, width, height, 0); +} + +void Warrior::prepareAttack() { + attackCooldown = SWING_COOLDOWN; + projectile = new SwordSwing(this, orientation, power); + + if (!Player::swordSound) { + Player::swordSound = al_load_sample("resources/sound/sword.wav"); + } + + al_play_sample(Player::swordSound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/warrior.h b/src/warrior.h new file mode 100644 index 0000000..6e67383 --- /dev/null +++ b/src/warrior.h @@ -0,0 +1,42 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef WARRIOR_H +#define WARRIOR_H + +#include "player.h" +#include + +const double SWING_DURATION = 0.25; +const double SWING_COOLDOWN = 0.5; + +class Warrior : public Player { +public: + static ALLEGRO_BITMAP *warrior; + double attackTime; + + Warrior(); + ~Warrior(); + + std::string getName(); + void collisionWith(Entity *entity); + void render(double edt); + void prepareAttack(); + void renderScreen(int x, int y); +}; + +#endif // WARRIOR_H diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..2044e31 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,61 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "window.h" + +Window *Window::instance = 0; + +Window::Window() { + +} + +Window::~Window() { + +} + +Window *Window::getInstance() { + if (!instance) { + instance = new Window(); + } + + return instance; +} + +void Window::setSize(int width, int height) { + this->width = width; + this->height = height; +} + +int Window::getWidth() { + return this->width; +} + +int Window::getHeight() { + return this->height; +} + +BoundingBox Window::getBounds() { + return BoundingBox(windowPos.getX() - width / 2, + windowPos.getY() - height / 2, width, height); +} + +Vector2D Window::getWindowPos(Vector2D worldPos) { + BoundingBox bounds = getBounds(); + Vector2D newPos = Vector2D(worldPos.getX() - bounds.getMinX(), + worldPos.getY() - bounds.getMinY()); + return newPos; +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..a121955 --- /dev/null +++ b/src/window.h @@ -0,0 +1,47 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef WINDOW_H +#define WINDOW_H + +#include "bounding-box.h" + +class Window +{ +private: + int width; + int height; + + Window(); + +protected: + static Window *instance; + +public: + ~Window(); + + static Window *getInstance(); + void setSize(int width, int height); + int getWidth(); + int getHeight(); + BoundingBox getBounds(); + + Vector2D windowPos; + Vector2D getWindowPos(Vector2D worldPos); +}; + +#endif // WINDOW_H diff --git a/src/witch.cpp b/src/witch.cpp new file mode 100644 index 0000000..df76664 --- /dev/null +++ b/src/witch.cpp @@ -0,0 +1,74 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "witch.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Witch::witch = 0; +ALLEGRO_SAMPLE *Witch::sound = 0; + +Witch::Witch() { + life = 100; + power = 30; + speed = 256; + maxSpeed = speed; + weakness = MAGE; + width = 48; + height = 48; + gold = 3; +} + +Witch::~Witch() { +} + +void Witch::render(double edt) { + if (!witch) { + witch = al_load_bitmap("resources/graphics/witch.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(witch, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(witch, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Witch::getDeathParticles() { + Particle *particle = new Particle(2, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Witch::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/witch.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/witch.h b/src/witch.h new file mode 100644 index 0000000..19ab30f --- /dev/null +++ b/src/witch.h @@ -0,0 +1,38 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef WITCH_H +#define WITCH_H + +#include "monster.h" +#include +#include + +class Witch : public Monster { +public: + static ALLEGRO_BITMAP *witch; + static ALLEGRO_SAMPLE *sound; + + Witch(); + ~Witch(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void playSound(); +}; + +#endif // WITCH_H diff --git a/src/zombie.cpp b/src/zombie.cpp new file mode 100644 index 0000000..8014888 --- /dev/null +++ b/src/zombie.cpp @@ -0,0 +1,184 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "zombie.h" +#include "window.h" +#include "map.h" +#include + +ALLEGRO_BITMAP *Zombie::zombie = 0; +ALLEGRO_SAMPLE *Zombie::sound = 0; + +Zombie::Zombie() { + life = 60; + power = 25; + speed = 128; + maxSpeed = speed; + weakness = ALL; + width = 48; + height = 48; + gold = 1; +} + +Zombie::~Zombie() { +} + +void Zombie::render(double edt) { + if (!zombie) { + zombie = al_load_bitmap("resources/graphics/zombie.png"); + } + + Window *window = Window::getInstance(); + Vector2D windowPos = window->getWindowPos(position); + + al_draw_tinted_scaled_bitmap(zombie, al_map_rgb(255, 255, 255), + 0, 0, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + double t = immunity / 0.5; + if (t > 0.0) { + al_draw_tinted_scaled_bitmap(zombie, al_map_rgba_f(1.0, 1.0, 1.0, t), + 0, height, width, height, + windowPos.getX() - width / 2, windowPos.getY() - height / 2, width, height, flags); + } + + renderWeakness(); +} + +ParticleSystem *Zombie::getDeathParticles() { + Particle *particle = new Particle(3, 32, 32, 0.050, 1.0, 0.0, 1.0); + ParticleSystem *particleSystem = new ParticleSystem(particle, RADIAL_ACCEL_OUT, position, 100, 0, 0.3); + + return particleSystem; +} + +void Zombie:: +artificialIntelligence(double dt, Map *map, std::vector entities) { + if(inercia <= 0) { + int interval = 9 - 0 + 1;//MAX-MIN+1 + int numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + state = STOP; + if(numRand > 8 ) { + state = MOVE; + } + inercia = 1.0; + if(state == MOVE) { + inercia = 1.0; + interval = 7 - 0 + 1;//MAX-MIN+1 + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDx = dxMoster[numRand]; + numRand = 0 + int(interval * (double)rand() /((double)RAND_MAX + 1.0)); + stepDy = dyMoster[numRand]; + if (stepDx > 0) { + flags = ALLEGRO_FLIP_HORIZONTAL; + } + } + } + + for(unsigned int i = 0; i < entities.size(); i++) { + if(entities[i]->type == PLAYER) { + double distance = position.distanceTo(entities[i]->position) ; + if(distance < distanceAlert) { + + inercia = 0; + state = FOLLOW_PLAYER; + targetPlayer = ((Player*)entities[i]); + if(distance < distanceAttack) { + state = ATTACK; + } + } + } + } + + Vector2D curPos; + Vector2D move; + BoundingBox box ; + switch(state) { + case STOP: + inercia-=dt; + break; + + case MOVE: + curPos = position; + move = Vector2D(stepDx,stepDy); + move = move.mult(speed * dt); + position = position.add(Vector2D(move.getX(), 0)); + box = hasMapCollision(map); + if (box.getMaxX() - box.getMinX() > 0) { + if (move.getX() > 0) { + int dx = (position.getX() + width / 2) - box.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, move.getY())); + box = hasMapCollision(map); + if (box.getMaxY() - box.getMinY() > 0) { + if (move.getY() > 0) { + int dy = (position.getY() + height / 2) - box.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + inercia-=dt; + break; + + case FOLLOW_PLAYER: + Vector2D aux = position.mult(-1); + Vector2D movTarget = targetPlayer->position.add(aux); + movTarget = movTarget.normalize(); + movTarget = movTarget.mult(speed * dt); + + position = position.add(Vector2D(movTarget.getX(), 0)); + BoundingBox box2 = hasMapCollision(map); + if (box2.getMaxX() - box2.getMinX() > 0) { + if (movTarget.getX() > 0) { + int dx = (position.getX() + width / 2) - box2.getMinX(); + position.setX(position.getX() - dx - 1); + } else { + int dx = box2.getMaxX() - (position.getX() - width / 2); + position.setX(position.getX() + dx + 1); + } + } + curPos = position; + position = position.add(Vector2D(0, movTarget.getY())); + box2 = hasMapCollision(map); + if (box2.getMaxY() - box2.getMinY() > 0) { + if (movTarget.getY() > 0) { + int dy = (position.getY() + height / 2) - box2.getMinY(); + position.setY(position.getY() - dy - 1); + } else { + int dy = box2.getMaxY() - (position.getY() - height / 2); + position.setY(position.getY() + dy + 1); + } + } + break; + + } +} + +void Zombie::playSound() { + if (!sound) { + sound = al_load_sample("resources/sound/zombie.wav"); + } + + al_play_sample(sound, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} diff --git a/src/zombie.h b/src/zombie.h new file mode 100644 index 0000000..3628884 --- /dev/null +++ b/src/zombie.h @@ -0,0 +1,39 @@ +/* +Dungeon Looters - SPJAM 2012 +Copyright (C) 2012 Fellipe Augusto Ugliara, Jeferson Rodrigues da Silva + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef ZOMBIE_H +#define ZOMBIE_H + +#include "monster.h" +#include +#include + +class Zombie : public Monster { +public: + static ALLEGRO_BITMAP *zombie; + static ALLEGRO_SAMPLE *sound; + + Zombie(); + ~Zombie(); + + void render(double edt); + ParticleSystem *getDeathParticles(); + void artificialIntelligence(double dt, Map *map, std::vector entities); + void playSound(); +}; + +#endif // ZOMBIE_H