The hardest thing that RPG makers face nowadays is the object system. The object system is everything from a soda can to the guy who sells magazines behind the counter in the dirty book store (yeah, we all know you put one in your game, don't be shy ;)). Anyways, I see awful examples of such an object system every day of my life. I see NPC's that just sit there...and don't do anything. I see NPC's that are incapable of nothing more than a random movement and message. I see objects that are limited to their original script. I see many things that are horrible and should be eliminated from each and every engine on this planet.
The first thing that a person should do if they want to make a complete RPG is make a complete and totally functional object system. A functional and complete object system will allow NPC's to walk through doors, activate scripts, be controlled, hold items, talk, and drop items. Instead of having one character and other "npcs" which are controlled through some other routine, we should put all of the objects and the character on the same exact level. Here's an example.
SUB UpdateNPCS FOR uNF=1 to ActiveNPCS SELECT CASE uNF CASE CurrentlyControlledCharacter(End of psuedo code)
MoveNPC uNF, Keyboardismovinghorizontal, Keyboardismovingvertical CASE ELSE SELECT CASE ObjectData(uNF) CASE RandomlyMoves MoveNPC uNF, RandomPlaceX, RandomPlaceY CASE IsMovingToAPoint MoveNPC uNF, ObjectPointToMoveTo(uNf,0), ObjectPointToMoveTo(uNF,1) CASE IsStandingStill AnimateNPC uNF END SELECT END SELECT NEXT END SUB SUB MoveNPC Number,MoveToX,MoveToY Test=Map(MoveToX,MoveToY) select CASE TEST case Walkable ObjectLocation(Number,0)=MoveToX:ObjectLocation(number,1)=MoveToY case IsAScriptTile ActivateScript END SELECT END SUB
Not so hard, eh? I bet you didn't think that a totally efficient and active object system would be so short. Now that you have this out of the way, you can add things like an items list for each NPC (watch your RAM usage!!). Then, you could possibly trade and sell items to every NPC.
LINK /QU SVGAQB.LIB, SVGAQB.QLB, NUL, BQLB45.LIB
Then, to start the QB IDE using the library, type QB /L SVGAQB
To use ZSVGA in your programs you must use a specific header. At the top of all ZSVGA programs enter:
DEFINT A-Z '$INCLUDE: 'SVGABC.BI'
There ya go, your now ready to use ZSVGA functions in your programs.
IF WHICHVGA THEN PRINT "SVGA Video Card Detected!" ELSE PRINT "SVGA Video Card Not Detected!": END END IF
Now let's get into hi res modes! Yippee! =]
For most of these articles I will be using 640x480 modes, you should have at least 1 meg of video ram which can be checked via WHICHMEM. To enter a video mode simply use:
IF Res640 = 0 THEN PRINT "Could not enter 640x480 mode!": END
To plot a single pixel you can simply use the DrwPoint function. The syntax goes like this:
DrwPoint (Mode%, Color%, X%, Y%)
Simple, eh? =]
You may wonder what Mode% is. Well, it's nothing but the pixel write mode. You don't really have to worry about it at this point (Pardon the pun), just set it to 1 for now. =] In case your interested the pixel write modes go like this:
1 = SET 2 = XOR 3 = OR 4 = AND
Now, let's plot da pixels! Here is some example code:
RANDOMIZE TIMER 'Seed the random number generator FOR i = 1 TO 250 'Begin our FOR loop x = INT(RND * 639) + 1 'Randomize the x axis position y = INT(RND * 479) + 1 'Randomize the y axis position c = INT(RND * 255) + 1 'Randomize the pixel color DrwPoint 1, c, x, y 'Plot the pixel! NEXT i 'End our loop
DrwLine (Mode%, Color%, X1%, Y1%, X2%, Y2%)
Like, the point function this is pretty much self-explanatory. Like the DrwPoint function, set Mode% to 1 for now. Here's some more example code:
RANDOMIZE TIMER 'Seed the random number generator FOR i = 1 TO 100 'Begin our FOR loop x1 = INT(RND * 639) + 1 '\ y1 = INT(RND * 479) + 1 '|Randomize all the points! x2 = INT(RND * 639) + 1 '| y2 = INT(RND * 479) + 1 '/ c = INT(RND * 255) + 1 'Randomize the color DrwLine 1, c, x1, y1, x2, y2 NEXT i 'End our loop
Null = ResText
That's it for this article of ZSVGA. It's short, due to time constraints, but the next one should be bigger. In the next article I'll explain more graphic functions including using page flipping for smooth animation. Until then, be sure to explore SVGABC25.TXT to learn about other functions. Signing off...
You will hear time and time again how libraries encourage laziness, they're not "real" programming because you're using somebody else's code, so on and so forth. From the other side of the argument comes the people who claim that the use of libraries have made them much better programmers. Let's look at both sides of the argument.
Let's be honest: if you use a library, that is code you didn't write. Accept it. However, you also did not write the code behind SCREEN 13, PRINT, and the legions of other QB commands that exist. There are a ton of arguments from there..."Libraries are not true QB code because they didn't come with QB", "You gotta write yer own code!", and my personal favorite "Libraries in QB are written by amateurs, real programmers use pro libs". Don't make me laugh people. These same people will write a Windows-based program, or a DOS program in C++. How many libraries do each of these require? Have any of these people actually looked into what really goes into a Windows program for example? How many DLLs and components from things like DirectX go into these applications? "But, those are professional libraries!" Who cares, it's CODE YOU DIDN'T WRITE! I don't care if they were written by Bill Gates himself, it is still code you didn't write...yet not only do you use it, but you shun QB coders who use libraries like Dash. Does the word "hypocrisy" ring a bell at this point? QB libraries have, without a fraction of a doubt, raised the standards of QB programs over the last two years, and this will continue to persist.
Now...on the other hand, we have legions upon legions of "newbies" entering the QB world, each with no experience and no common sense. They see a library advertised on a webboard or website and think "Wow! All my troubles are already fixed!!". These kids don't even know how to use PRINT yet, and they can rattle off every known function in DirectQB for example. These people anger me more than the hypocrites who oppose libraries. I get so many emails and ICQ messages from these people, begging for help because they can't figure out why the newest library function doesn't work, when all it usually is is that they forgot a simple little thing they needed to do in QB code to solve it. For example, it usually helps to set the screen mode before using GSsprite. This is a concept these people don't understand. They figure "Hey! The library is supposed to do that kind of work for me!! I don't understand!". Hence the reason libraries are dangerous to the newbie. They have not yet grasped the functionality of the language and yet they try to wield such power. And in almost every case, this will backfire on them, driving home even further the arguments that libraries are bad.
The key point to this is this: Libraries are a powerful tool that in the right hands, can have great use, but in the wrong hands, can be painfully destructive. These arguments will persist, and there will never be a victor. Period. So, whichever side you're on, you're just going to have to deal with that truth.
The skinny: Download this game if you enjoy a "rebirth" of sorts, or are looking for something to kill some time with. It is fun to play, and that's what we play games for in the first place.
You can pick up the Hack-Man series at WidomDude's Domain
Review by Nekrophidius
This pic is unique, It is very rare to have games in QB with weather-effects,
Basically what this person is saying is that they would rather rely on the work of others, rather than their own. They would do well working for Microsoft.
TONS of example code in all languages, a great source of information.
Follow the latest news on the QBRPG scene. Almost 100 RPGs available for download, all done in QB.
THE ALL BASIC CODE
If it's BASIC, they got it. Thousands of downloads for all kinds of BASIC.
DEFINT A-Z TYPE grasspoint x AS INTEGER y AS INTEGER angle AS INTEGER END TYPE RANDOMIZE TIMER ngrass = 1000 DIM SHARED grass(ngrass) AS grasspoint DIM SHARED presin(360) AS INTEGER FOR lp = 0 TO ngrass grass(lp).x = RND * 320 grass(lp).y = RND * 200 grass(lp).angle = (grass(lp).x MOD 360) + RND * 30 - ((200 - grass(lp).y) ^ .5) * 10 NEXT FOR lp = 0 TO 360 presin(lp) = SIN(lp * 3.14159 / 180) * 128 NEXT SCREEN 7 PALETTE 0, 4 OUT &H3C8, 4 OUT &H3C9, 0 OUT &H3C9, 23 OUT &H3C9, 0 PALETTE 1, 1 OUT &H3C8, 1 OUT &H3C9, 0 OUT &H3C9, 16 OUT &H3C9, 0 DO SCREEN 7, , d, (d + 2) MOD 4 CLS d = (d + 1) MOD 4 FOR lp = 0 TO ngrass grass(lp).angle = (grass(lp).angle + 350) MOD 360 LINE (grass(lp).x, grass(lp).y)-(grass(lp).x + ABS(presin(grass(lp).angle)) \ 60 + 1, grass(lp).y + 1 + ABS(presin(grass(lp).angle)) \ 60), 1 NEXT FOR lp = 0 TO ngrass LINE (grass(lp).x, grass(lp).y)-(grass(lp).x + ABS(presin(grass(lp).angle)) \ 60, grass(lp).y - 2 + ABS(presin(grass(lp).angle)) \ 100), 2 NEXT LOOP UNTIL INKEY$ <> ""
Thanks for reading, and prepare for the next issue, out November 24th!