/****************************************
* Variables *
****************************************/
let ObjectExtraProperties = [];
let OBJECT_ID = 0;
let OBJECT_ACCEL = 1;
let OBJECT_MAXMINSPEED = 2;
let OBJECT_ANGULARVELOCITY = 3;
/****************************************
* Public Functions *
****************************************/
function Obj_SetAcceleration(obj, accel){
let indx = Obj_getIndex(obj);
if(indx != -1){
ObjectExtraProperties[indx] = [obj, accel, Obj_getMaxMinSpeedByIndex(indx), Obj_getAngularVelocityByIndex(indx)];
}
else{
ObjectExtraProperties = ObjectExtraProperties ~ [[obj, accel, NULL, 0]];
}
}
function Obj_SetMaxMinSpeed(obj, speed){
let indx = Obj_getIndex(obj);
if(indx != -1){
ObjectExtraProperties[indx] = [obj, Obj_getAccelerationByIndex(indx), speed, Obj_getAngularVelocityByIndex(indx)];
}
else{
ObjectExtraProperties = ObjectExtraProperties ~ [[obj, 0, speed, 0]];
}
}
function Obj_SetAngularVelocity(obj, angularVelocity){
let indx = Obj_getIndex(obj);
if(indx != -1){
ObjectExtraProperties[indx] = [obj, Obj_getAccelerationByIndex(indx), Obj_getMaxMinSpeedByIndex(indx), angularVelocity];
}
else{
ObjectExtraProperties = ObjectExtraProperties ~ [[obj, 0, NULL, angularVelocity]];
}
}
function Obj_GetAcceleration(obj){
return Obj_getAccelerationByIndex(Obj_getIndex(obj));
}
function Obj_GetMaxMinSpeed(obj){
return Obj_getMaxMinSpeedByIndex(Obj_getIndex(obj));
}
function Obj_GetAngularVelocity(obj){
return Obj_getAngularVelocityByIndex(Obj_getIndex(obj));
}
function Obj_Update(){
let len = length(ObjectExtraProperties);
descent(i in 0..len){
if(Obj_BeDeleted(ObjectExtraProperties[i][OBJECT_ID])){
ObjectExtraProperties = erase(ObjectExtraProperties, i);
}
else{
let obj = ObjectExtraProperties[i][OBJECT_ID];
let accel = ObjectExtraProperties[i][OBJECT_ACCEL];
let newSpeed = Obj_GetSpeed(obj) + accel;
let angularVelocity = ObjectExtraProperties[i][OBJECT_ANGULARVELOCITY];
let newAngle = Obj_GetAngle(obj) + angularVelocity;
if(ObjectExtraProperties[i][OBJECT_MAXMINSPEED] != NULL){
let maxMinSpeed = ObjectExtraProperties[i][OBJECT_MAXMINSPEED];
if((accel<0 && newSpeed<maxMinSpeed) || (accel>0 && newSpeed>maxMinSpeed)){
newSpeed = maxMinSpeed;
}
Obj_SetSpeed(obj, newSpeed);
Obj_SetAngle(obj, newAngle);
}
}
}
}
/****************************************
* Private Functions *
****************************************/
function Obj_getIndex(obj){
let len = length(ObjectExtraProperties);
ascent(i in 0..len){
if(ObjectExtraProperties[i][OBJECT_ID] == obj){
return i;
}
}
return -1;
}
function Obj_getAccelerationByIndex(indx){
return ObjectExtraProperties[indx][OBJECT_ACCEL];
}
function Obj_getMaxMinSpeedByIndex(indx){
return ObjectExtraProperties[indx][OBJECT_MAXMINSPEED];
}
function Obj_getAngularVelocityByIndex(indx){
return ObjectExtraProperties[indx][OBJECT_ANGULARVELOCITY];
}#TouhouDanmakufu
#Title[Extra Object Bullet Functions Test]
#Player[FREE]
#ScriptVersion[2]
script_enemy_main
{
#include_function "\lib\ExtraObjectFunctions.txt"
let count=0;
@Initialize
{
SetLife(10000);
}
@MainLoop
{
if(count == 60){
let obj = Obj_Create(OBJ_SHOT);
Obj_SetPosition(obj, GetX, GetY);
Obj_SetAngle(obj, 90);
Obj_SetSpeed(obj, 0);
ObjShot_SetGraphic(obj, RED01);
Obj_SetAcceleration(obj, 0.05);
Obj_SetMaxMinSpeed(obj, 5);
Obj_SetAngularVelocity(obj, 0.3);
}
Obj_UpdateObjects();
count++;
}
@Finalize
{
}
@DrawLoop
{
}
}Mannosuke is gone.Aww man
Then I bet you also seen that dude on niconico creating Danmakufu tetris?
If you live in China, can't you like easy ship the things from Japan (should be not much to pay the shipping prices right?) I think Paletweb was still selling copies of Touhou games.
Oh pushing limits happens often, that is why I mentioned the effects. Currently I have this burning aura effect where like alot of particles are spawned to create a burning effect. It looks superb but is a huge strain on the engine :V You can see the effect on my youtube channel if you look for DoubleVla.
let behavior = [
[0, 1, 90, 4, 0.01, 5, RED01],
[30, NULL, NULL, -1, 0.01, 5, RED01],
[60, NULL, NULL, 0, 0.01, 5, RED01]
];
let obj = CreateObjectShotA(GetX, GetY, 10, behavior);
This has the same effect asCreateShotA(0, GetX, GetY, 10);
SetShotDataA(0, 0, 1, 90, 4, 0.01, 5, RED01);
SetShotDataA(0, 30, NULL, NULL, -1, 0.01, 5, RED01);
SetShotDataA(0, 60, NULL, NULL, 0, 0.01, 5, RED01);
FireShot(0);
/************************************************************
*
* Constants
*
***********************************************************/
let OBJ_ID = 0;
let OBJ_START_FRAME = 1;
let OBJ_CURRENT_BEHAVIOR = 2;
let BEHAVIOR_DURATION = 0;
let BEHAVIOR_VELOCITY = 1;
let BEHAVIOR_ANGLE = 2;
let BEHAVIOR_ANGULAR_VELOCITY = 3;
let BEHAVIOR_ACCELERATION = 4;
let BEHAVIOR_MAX_MIN_SPEED = 5;
let BEHAVIOR_GRAPHIC = 6;
let MAX_BEHAVIOR_COUNT = 8;
/************************************************************
*
* Variables
*
***********************************************************/
let BehaviorShots = [];
let BehaviorShotBehaviors = [];
/************************************************************
*
* Public Functions
*
***********************************************************/
function CreateObjectShotA(x, y, delay, behavior){
let obj = Obj_Create(OBJ_SHOT);
Obj_SetPosition(obj, x, y);
ObjShot_SetDelay(obj, delay);
let startFrame = CurrentFrame();
//id, starting frame, current behavior, behavior list
let behaviorShot = [obj, startFrame, 0];
let len = length(behavior);
let behaviorShotBehavior = [];
if(len < MAX_BEHAVIOR_COUNT){
behaviorShotBehavior = behaviorShotBehavior ~ behavior;
loop(MAX_BEHAVIOR_COUNT-len) {
behaviorShotBehavior = behaviorShotBehavior ~ [[-1, 0, 0, 0, 0, 0, 0]];
}
} else if (len > MAX_BEHAVIOR_COUNT){
ascent(i in 0..MAX_BEHAVIOR_COUNT) {
behaviorShotBehavior = behaviorShotBehavior ~ [behavior[i]];
}
}
BehaviorShots = BehaviorShots ~ [behaviorShot];
BehaviorShotBehaviors = BehaviorShotBehaviors ~ [behaviorShotBehavior];
return obj;
}
function ObjectShotA_Run(){
let len = length(BehaviorShots);
OutputDebugString(0, "len", len);
descent(i in 0..len){
if(Obj_BeDeleted(BehaviorShots[i][OBJ_ID])){
BehaviorShots = erase(BehaviorShots, i);
BehaviorShotBehaviors = erase(BehaviorShotBehaviors, i);
}
else{
let behaviorShot = BehaviorShots[i];
let behaviorShotBehavior = BehaviorShotBehaviors[i];
BehaviorShot_updateState(behaviorShot, behaviorShotBehavior);
BehaviorShot_updateAttributes(behaviorShot, behaviorShotBehavior);
}
}
}
/************************************************************
*
* Private Functions
*
***********************************************************/
function BehaviorShot_updateAttributes(behaviorShot, behaviorShotBehavior){
let obj = behaviorShot[OBJ_ID];
let behaviors = behaviorShotBehavior;
let currentBehaviorIndex = behaviorShot[OBJ_CURRENT_BEHAVIOR];
let currentBehavior = behaviors[currentBehaviorIndex];
let angularVelocity = currentBehavior[BEHAVIOR_ANGULAR_VELOCITY];
let acceleration = currentBehavior[BEHAVIOR_ACCELERATION];
let maxMinSpeed = currentBehavior[BEHAVIOR_MAX_MIN_SPEED];
let speed = Obj_GetSpeed(obj);
let angle = Obj_GetAngle(obj);
let newSpeed = speed + acceleration;
if((acceleration > 0 && newSpeed > maxMinSpeed) || (acceleration < 0 && newSpeed < maxMinSpeed)){
newSpeed = maxMinSpeed;
}
let newAngle = angle + angularVelocity;
Obj_SetSpeed(obj, newSpeed);
Obj_SetAngle(obj, newAngle);
}
function BehaviorShot_updateState(behaviorShot, behaviorShotBehavior){
let obj = behaviorShot[OBJ_ID];
let startFrame = behaviorShot[OBJ_START_FRAME];
let timePassed = CurrentFrame() - startFrame;
let behaviors = behaviorShotBehavior;
let o = BehaviorShot_getBehaviorShotIndex(obj);
let len = length(behaviors);
descent(i in 0..len){
let behavior = behaviors[i];
let triggerTime = behavior[BEHAVIOR_DURATION];
if( triggerTime >= 0 && timePassed - triggerTime == 0){
BehaviorShot_setBehavior(obj, behavior);
BehaviorShots[o] = [obj, startFrame, i];
}
}
}
function BehaviorShot_setBehavior(obj, behavior){
let speed = behavior[BEHAVIOR_VELOCITY];
let angle = behavior[BEHAVIOR_ANGLE];
let graphic = behavior[BEHAVIOR_GRAPHIC];
if(speed != NULL){
Obj_SetSpeed(obj, speed);
}
if(angle != NULL){
Obj_SetAngle(obj, angle);
}
ObjShot_SetGraphic(obj, graphic);
}
function BehaviorShot_getBehaviorShotIndex(obj){
let len = length(BehaviorShots);
ascent(i in 0..len){
let behaviorShot = BehaviorShots[i];
if(behaviorShot[OBJ_ID]== obj){
return i
}
}
return -1
}
function BehaviorShot_getBehaviorShot(obj){
let len = length(BehaviorShots);
ascent(i in 0..len){
let behaviorShot = BehaviorShots[i];
if(behaviorShot[OBJ_ID]== obj){
return behaviorShot;
}
}
RaiseError("Can't find obj.", "BehaviorShot Error");
}
function BehaviorShot_getBehaviorShotBehavior(obj){
let len = length(BehaviorShots);
ascent(i in 0..len){
let behaviorShot = BehaviorShots[i];
if(behaviorShot[OBJ_ID]== obj){
return BehaviorShotBehaviors[i];
}
}
RaiseError("Can't find obj.", "BehaviorShot Error");
}
function debugShot(obj, i){
let behaviorShot = BehaviorShot_getBehaviorShot(obj);
let behaviorShotBehavior = BehaviorShot_getBehaviorShotBehavior(obj);
OutputDebugString(1, "obj", obj);
OutputDebugString(2, "OBJ_START_FRAME", behaviorShot[OBJ_START_FRAME]);
OutputDebugString(3, "OBJ_CURRENT_BEHAVIOR", behaviorShot[OBJ_CURRENT_BEHAVIOR]);
debugBehavior(behaviorShotBehavior[i]);
}
function debugBehavior(b){
OutputDebugString(4, "BEHAVIOR_DURATION", b[BEHAVIOR_DURATION]);
OutputDebugString(5, "BEHAVIOR_VELOCITY", b[BEHAVIOR_VELOCITY]);
OutputDebugString(6, "BEHAVIOR_ANGLE", b[BEHAVIOR_ANGLE]);
OutputDebugString(7, "BEHAVIOR_ANGULAR_VELOCITY", b[BEHAVIOR_ANGULAR_VELOCITY]);
OutputDebugString(8, "BEHAVIOR_ACCELERATION", b[BEHAVIOR_ACCELERATION]);
OutputDebugString(9, "BEHAVIOR_MAX_MIN_SPEED", b[BEHAVIOR_MAX_MIN_SPEED]);
OutputDebugString(10, "BEHAVIOR_GRAPHIC", b[BEHAVIOR_GRAPHIC]);
}
#TouhouDanmakufu
#Title[Test]
#Player[FREE]
#ScriptVersion[2]
script_enemy_main
{
#include_function ".\BehaviorShot.dnh"
let frame = 0;
@Initialize
{
SetLife(1);
}
@MainLoop
{
if (frame == 60){
CreateBehaviorShot(GetCenterX, GetCenterY, 10, [
[0, 5, 90, 4, -0.1, 1, 1],
[30, NULL, NULL, -1, 0, 0, 1],
[60, NULL, NULL, 0, 0.01, 3, 1]
]);
}
BehaviorShot_Run();
frame++;
}
@Finalize
{
}
@DrawLoop
{
}
}CreateObjectShotA(starting_x, starting_y, delay, [
[time_to_modify_behavior, speed, angle, angular_velocity, acceleration, max/min_speed, graphic]
]);You can have up to 8 of those arrays inside the main array which correspond to up to 8 SetShotDataA functions. Don't forget the commas between the array elements in the big array.[...]I expected to see a code what enables you to switch characters in game[...]
You can't change characters in a script. The closest you can do to imitate that is to make a player script that holds all the players you wanna switch between. The easiest way to handle the switching in the Ikareimu script would be to change the bullet properties themselves like I did and change which sprite is drawn on the character at the same time via common data.
Actually, with the way I plan to design it, the character script should change the common data and all the other scripts will read the common data, but since I don't have an Ikareimu character script yet, the spellcard script is calling the color and shield functions in its place for now.
Hmm, when I've learned enough I'll look into it. I never learned any programming ever so I'm a n00b in these areas. Anyway, it was just an old idea of mine for a Touhou game where you can collect weapons like in old-school shmups instead of choosing the shot type when you start the game. And a scoring system based on that idea, like score multipliers for how much you've changed weapon to another and stuff.
script_enemy_main {
#include_function "lib\Ikareimu\Enemy.dnh"
// Following two variables are part of a work around. Have them at all times.
let autoDeathCounter = 600;
let FinalizeRun = false;
let count=0;
@Initialize {
EnemySystem_Initialize;
// Set the life to how much health you would like the enemy to have plus 100.
// This is a work around for an issue Danmakufu cannot address easily.
SetLife(101);
}
@MainLoop {
// This if statement is the "real" @MainLoop. Sorry, but this is part of the
// work around mentioned above.
if(GetLife > 100){
count++;
}
// End of "real" @MainLoop
if(GetLife < 100){
// This if statement is the "real" @Finalize. Yup. Part of the work around.
if(!FinalizeRun){
FinalizeRun = true;
// Things like visual and sound effects during death must be handled manually here.
}
// End of "real" @Finalize.
autoDeathCounter-=1;
if(autoDeathCounter == 0){
VanishEnemy;
}
}
EnemySystem_Run;
}
@Finalize {
EnemySystem_Finalize;
}
@DrawLoop {
// This if statement is the "real" @DrawLoop.
if(GetLife > 100){
}
// End of "real" @Drawloop.
}
}
So I guess bombs and homing shots fuck everything over? Though I can see a work around for homing shots (Josette Y comes to mind), bombs will still kill off enemies.Yeah, but if you're making Ikaruga-style gameplay with my library, you'll almost definitely be using the player character specific functions I built in as well which handles the homing lasers specifically for this workaround. And I'd hope you'd remember to restrict the usable players for your scripts to only your Ikaruga-style player character.
Actually, make the workaround number be 10000, at least then bombs wont kill off the enemy.Yeah I suppose I should increase it anyway.
Also, to spare some processing power (I guess), you could have an if(GetEnemyShotCount<1 && GetLife<10000){ VanishEnemy; } statement, to kill off the enemy if there are no bullets left on the screen to handle.Though I doubt much processing power is lost from having them stay when there's nothing else to handle, that's probably a good idea still. Added.
Needs bullet shooty sounds, for enemies, the player, and especially for master spark. If it's possible to take the master spark sound out of the player's se folder(seBomb_MarisaB.wav), then do it. A shield absorption sound would also be nice.
Fun to play, even if the anti-ghosting on my keyboard means I have to fight with the controls when I change colors. Also, it's just occurred to me that since discerning black and white is Sikieiki's power, that maybe she should be a second character. :P
Also, during one of my runs, I could have sworn I somehow deathbombed...that is, I hit the "bomb" key after I got hit and lived.
Chaining is neat, even if I can't seem to get the hang of it.
May I suggest life counter somewhere else than under laser bar?
Not a big problem, but at least I misunderstand for first time I play (spamingbomblaser when laser bar was fill with x4 = 4 bar!)
Chaining system cool!
Um...
Your script crashed danmakufu...
PERNAMENTLY...
D:
Edit: hahaha oh wow that was purely due to my own incompetence
What.The final one made my day.
(http://i44.photobucket.com/albums/f28/Blargel/difficulties.png)
Yes, I really plan on making that last difficulty.
The final one made my day.
I just tested v0.5.That's to prevent you from spamming C
I don?t know why but it feels that the switching takes too long.
Also what difficulty is this suposed to represent? :V
Dear god this is not stage 1. There is no fucking way this is stage 1.Yeah, I know there's way too many bullets for a Touhou-style stage 1, but mashing together Touhou patterns with Ikaruga gameplay is a lot harder to balance than you would think. If you don't have impossible walls of bullets coming at you, there's no point for the polarity switching. If there's too many bullets, it doesn't seem like Touhou-style anymore. You gotta remember that a lot of the time, you need to realize what color it is best to switch to. For example, against Cirno, obviously it's better to be blue. Once there is a giant spam of red fairies on top of Cirno though at the very end before Marisa, it's better to become red and focus on dodging her big blue bullets instead.
I always figured that the stage you had in the demos wasn't characteristic of stage 1 difficulty... stage 1 lunatic of UFO difficulty maybe, but not stage 1. Bear in mind, this is on normal mode...and I've 1cc'd most of Touhou games on hard.
Also, you made master spark harder, you twisted little freak! XDYou gotta admit, that version is a lot more Touhou-ish though. :V
Anyways, I took a stroll through fuckingwhat mode, just to see what it was like. I've never played the original version of flanchan, but somehow I think this is harder. I can't last two seconds without getting hit during the boss... and I mean this in the absolute literal sense. I can't wait to see Naut's reaction.I can't last long either. The way I "balanced" it was by turning on invulnerability and going "Eh, there's gaps. Someone will find a way to live." Just as a side note, I've managed to actually make it to Marisa without dying on Fuckingwhat mode. She completely demolished all my lives on the first nonspell.
For some odd reason, Marisa has a longer delay between having her HP bar depleted and declaring her spell now... hm.Yeah, I didn't want Marisa to declare immediately, but I ended up making the delay about a second too long so that it actually feels like it interrupts the battle flow. I realized this before I released this version, but it was 9am and I hadn't slept all night. I didn't want to spend another minute working on it. :P
The menu sound is loud. Really, really loud. Make it less loud. :VYes... yes it is. I really wish Danmakufu had volume control for sound. I guess I forgot about menu sounds when I was lowering the volume of the stolen ZUN sound. >:(
Addressing the alternate control schemes, I think it is absolutely awesome that you can here... but I'd like to mention something: Given that we are using Ikaruga gameplay here, it's reasonable to assume that the player is going to be using the switch colors key almost constantly... this was mentioned by someone else I talk to who has played Ikaruga, and I have to agree, you should be able to assign the switch colors key to the bomb/aimed laser thingies key, and have the bomb key go somewhere else. For instance, X is switch, and Ctrl is laser thingy. Especially this time around I have been fumbling with the switch colors key an awful lot, and this would help massively.Darn you, picky person! :V
Okay I'm trying the script this since I have spare time(art block due to lack of cging music) and I don't know what to do with it :V
What the hell is up with my jaw?Fuckingwhat is possible. With practice. Lots of practice. And masochism.
Anyway, AWESOME. Cirno made me lol.
I also took a look at Fuckingwhat. With invincibility, of course.
...I doubt that even Naut can beat that. I WANT A VIDEO!
BLARGER!!!!!!!Who's Blarger? :V
WHY ARE YOU SO AWESOME???
It's GREAT! Not to mention, this is also the best Menu Script I ever seen in my life, so much to learn from it!
Apart from that, this whole script reeks from AWESOME!!
Yes someone should make a video! And upload it to Nico too!
I like the rebalancing of FuckingWhat mode.The only thing I touched was Marisa's first spell for FuckingWhat. I had the great idea of making every spellcard in the game have something ridiculous and extra on FuckingWhat that would make the average player go "Fucking what." For example, 3x amount of stars in 3 different directions on Non-directional Laser and 3x the Sparks in Double Spark. I might consider making the sparks move and calling it "Non-directional Master Spark" or something.
Or reskewing...? Hmm.
I still like it.
Got a random update: Bad Apple (http://dl.dropbox.com/u/4234581/BadApple.rar).
Yes, in Danmakufu.
M-m-m-megabump!Damn you I was gonna do this!
Got a random update: Bad Apple (http://dl.dropbox.com/u/4234581/BadApple.rar).
Yes, in Danmakufu. No I wasn't crazy enough to construct everything out of bullets. I was just trying to kill time without working on the scripts I'm supposed to be working on. ('Cause you know, that would actually be productive.) It might be fun to look at the FrameDefine.dnh in there while you have the script. It's AWESOME. :V
Also, I might as well announce that I actually AM working on something, though it's coming along slowly because of limited time.
I demand you add matching danmaku to this.
Damn you I was gonna do this!:V
Although you did a much better job that what I could have done :V
And now to probe your scripts to learn how you managed to sync it so well :coolvee:
Edit: Ahaha I feel so dumb for doing it the way I did for my GET DOWN script (raw frame by frame work :V).
I demand you add matching danmaku to this.That would be difficult.
EDIT: ALSO, I GET AN ERROR SAYING THAT THERE WAS AN UNEXPECTED END OF ARCHIVE...WHAT IS THIS?Huh?
For the error, seem like it'll error if you fire some shot during play.
Huh?
Shoot the Bullet Engine for Danmakufu (http://bulletforge.org/u/blargel/p/shoot-the-bullet-engine/)Jeses fucking christ
Yo, I'm back with more useless shit. Well, this time it's only useless because it doesn't do what its name implies it's supposed to be doing. Yet. I'm working on it, I swear!I love you.
Shoot the Bullet Engine for Danmakufu (http://bulletforge.org/u/blargel/p/shoot-the-bullet-engine/)
Shoot the Bullet Engine for Danmakufu (http://bulletforge.org/u/blargel/p/shoot-the-bullet-engine/)
:oThe photo thing would be near the impossible...take an automatic screen shot are resize it, all of that coded in danmakufu ? hum...?
but honestly... it doesn't seem that hard... just tedious... all you have to do is check the position of the camera + the length and width... then check whether the boss is there... if it is... then create an object or player shot that damages the boss on top of it... for shots, just a simple DeleteEnemyShotInCircle (don't know how that would work for rectangles though... :V) then add an object effect and a timer that sets the reducing length and width... all put into a single if(GetKeyState(VK_SHOT)==KEY_PUSH || GetKeyState(VK_SHOT)==KEY_HOLD) statement... and of course adding if(cameracharge==100) or something like that... :D
All falls into having enough time... or not getting too lazy...
I would sure be interested in help if there will be a "TouhouDanmakufu Bunkachou - MotK Edition" (most decent, till up to pros, scripters using thier own spellcards and you have to survive theshitstormbullet curtains).
I call 6th stage boss.
I call for 4th Stage then.Speaking of BlueGraphics, today he gave me a trial version of Touhou Ronald Project. (http://www.mediafire.com/?vzjqhmnnzyz)
but we are getting off-topic here, so this should be a discussion in another thread.
and for now get?s get back to topic!
EDIT:
I just remmembered this. (http://www.youtube.com/watch?v=nqDXqn1ze1Y)
I have the Aya scriptNO WAY! THAT'S IMPOSSIB-- oh wait it isn't impossible...
I'd love to see what you got, but YouTube is kinda screwed up on my end. It had refused to load any videos and lately it doesn't load period.
Not unless you don't delete them. Bigger effect objects take longer to process. You'd also need to hide the current player, as well as detect collisions and graze properly. Unless you're doing something particularly batshit, I wouldn't recommend it.Common Data and Effect Spamming is somewhat my speciality.Yes, I've tried it, lol.
let variable = 0;
task DoIt{
loop{
Increase(variable,1);
yield;
}
}
funtion Increase(v,n){
if(GetCommonData("STAGESTATE")=="NORMAL"){v+=n;} //When Playing
if(GetCommonData("STAGESTATE")=="SLOW"){v+=n/2;} //When Taking a photo
if(GetCommonData("STAGESTATE")=="PAUSE1"){v+=0;} //When Pausing the game
if(GetCommonData("STAGESTATE")=="PAUSE2"){v+=0;} //When you gor hit
}EDIT : Well, isn't that the wrong thread ? Okay I stop spamming Blargel thread.
Whoops (http://www.youtube.com/watch?v=zRDOnhch7JI)
Who says it's that hard :V only took a few hours max... I'm probably gonna trash this cause I wouldn't wanna steal Blargel's idea, and I still have my game to do...
Note: Excluding the DrawLoop portion of Naut's Sanae I did not look at anyone's scripts to do this... (and fraps desynching the thing + youtube's visual raping + my comp sucking whenever it's showing object effects and stuff = >:( )
basically... An Aya player and 1 spell pattern (and a bullet library containing only 1 bullet type)... didn't bother to expand :V
Things I didn't do:
-Didn't make a menu/scene selection
-Sound effects of camera
-Boss movement slowing down while taking a picture (I slowed down the bullets though)
-Rectangle Detection (it currently detects a circle... got too lazy to make the rectangle, especially cause the photo effect object rotates... rotating rectangle >.<)
-Snapshots (I don't know how to use SaveSnapShot... or where it saves the snapshot)
-Charge Percentage won't draw for some reason... (also... I didn't put the % symbol... just numbers)
-Speed and size balancing (movement of the frame)... and some fixing with how the graphic changes when Aya takes a picture...
-Everything else balancing...
Will try to upload it to bulletforge...
EDIT:Uploaded (http://bulletforge.org/u/kylesky/p/stb-engine-to-be-scrapped/v/01/archive)
Note: I accidentally left the sanae player and some stuff in there... I just cleaned a copied version of my danmakufu (didn't download one), and used that for this... code's also a bit messy and needs some fixing...
Here's my useless Aya char (http://www.mediafire.com/download.php?qygzjej1w5z). She can't damage enemies or delete bullets and I don't plan to let her do so with normal bosses, but you can mess around with her charging, three move speeds, and picture taking. I think I imitated the ZUN version well. It's not on BulletForge because my engine doesn't really deserve an update on just a player char that can't do anything yet.
New version of StB engine! (http://bulletforge.org/u/blargel/p/shoot-the-bullet-engine/v/030)
Either something in the script is wrong, or my computer is not working right, because whenever I open up the running window, my screen goes black for a few seconds and tells me shows me an error message.
Btw... I am talking about, after I started the script and choose Aya.
It somehow doesn?t so anything on the main menu and I am stuck there because that one error.
It's just a thing you unpack in the script folder. :ohdear:
It's just a thing you unpack in the script folder. :ohdear:Hmm... so it is
#Player[FREE]And Danmakufu ran the scripts without crashing.That makes no sense whatsoever, but if you got it working, perhaps that little fix can help anyone else having the problem. If you changed the thing to FREE, are you sure you're using the correct Aya script though? If you had my earlier version of Aya, it might have been causing crashing.Well, I'm using Reimu A instead of your new Aya script, on your StB engine.
Well, I'm using Reimu A instead of your new Aya script, on your StB engine.
Yay! It finally works!
Does it also work with costum bulletsheets? (too lazy to try out)
Woah, that's never happened to me before. Can you reproduce this and tell me how it happened?
According to the code I wrote, that should absolutely never happen. I'm extremely confused...
script_enemy_main {
#include_function ".\bosslib\Boss.dnh"
let imgBoss = GetCurrentScriptDirectory ~ "img\wriggle.png";
let BossCutIn = GetCurrentScriptDirectory~"\boss.png";
let Frame = -120;
let Rotate = 0;
let AngA = 0;
let AngB = 179;
let Amount =1;
@Initialize {
InitializeStbBoss;
LoadGraphic(imgBoss);
SetTexture(imgBoss);
SetGraphicRect(0, 0, 48, 64);
SetX(GetClipMinX);
SetY(GetClipMinY);
SetStbMovePosition03(GetCenterX, GetClipMinY+130, 20, 8);
}
@MainLoop {
if(GetCurrentPicture==0){
AngB = 178;
Amount = 1;
}
if(GetCurrentPicture==1){
AngB = 181;
Amount = 1;
}
if(GetCurrentPicture==2){
AngB = 179.5;
Amount = 1;
}
if(Frame>0){
Attack;
}
if(Frame==60){
Frame=0;
SetStbMovePosition03(GetCenterX+rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
}
Frame++;
yield;
}
@DrawLoop {
DrawGraphic(GetX, GetY);
}
@Finalize {
if(GotSpellCardBonus){
PlaySE(GetCurrentScriptDirectory~"SFX\SpellBonus.wav");
}
}
task Attack{
Bullets(GetX, GetY, AngA);
AngA=AngA+AngB;
}
task Bullets(x, y, angle){
loop(Amount){
let obj = ObjStbShot_Initialize(x, y, 2, angle+Rotate, RED23, 0, 50, 8, RED);
Rotate=Rotate+360/5}
}
}task ManageFrameCounter {
loop {
Wait(1);
Frame++;
}
}
You should not do any MainLoop stuff to control the boss. Everything must be done with tasks and in every task, all yields must be replaced with the Wait function that is already built in. Even single yields must be replaced with Wait(1). However, the yield in MainLoop is still a yield. Do NOT put Wait(1); in the MainLoopUh I thought the builtin Wait function was for dialogues only
The Wait function I wrote is the thing that pauses boss logic at appropriate times.
If you absolutely want to do stuff with MainLoop, you can try adding this into your code.Code: [Select]task ManageFrameCounter {
loop {
Wait(1);
Frame++;
}
}
Put that task in, call it once in Initialize, and remove the Frame++; in the MainLoop. I believe it should work properly.
Uh I thought the builtin Wait function was for dialogues only
I believe it should work properly.
You have to learn how to handle everything in tasks.
Scripting Level while normaly scripting: Level 4
Scripting Level when only able to use tasks: Nameless Fairy
Is there anything special I need to know about making extra scripts for this? Is there documentation somewhere?There's plenty you need to know. You can take a look at the configMenus.dnh and the files in the boss\bosslib directory. They're all commented although not very well. I'll write some easier to read documentation when all the base features are completed. My wriggle1.dnh in the boss directory is a good example of how to do things though. Just for the most part, remember to put everything inside tasks and use the Wait function.
Scripting Level while normaly scripting: Level 4
Scripting Level when only able to use tasks: Nameless Fairy
script_enemy_main {
#include_function ".\bosslib\Boss.dnh"
let imgBoss = GetCurrentScriptDirectory ~ "img\wriggle.png";
let BossCutIn = GetCurrentScriptDirectory~"\boss.png";
let Frame = -120;
let Rotate = 0;
let AngA = 0;
let AngB = 179;
let Amount =1;
@Initialize {
InitializeStbBoss;
LoadGraphic(imgBoss);
SetTexture(imgBoss);
SetGraphicRect(0, 0, 48, 64);
SetX(GetClipMinX);
SetY(GetClipMinY);
SetStbMovePosition03(GetCenterX, GetClipMinY+130, 20, 8);
FakeMainLoop;
}
@MainLoop {
if(GetCurrentPicture==0){
AngB = 178;
Amount = 1;
}
if(GetCurrentPicture==1){
AngB = 181;
Amount = 1;
}
if(GetCurrentPicture==2){
AngB = 179.5;
Amount = 1;
}
yield;
}
@DrawLoop {
DrawGraphic(GetX, GetY);
}
@Finalize {
if(GotSpellCardBonus){
PlaySE(GetCurrentScriptDirectory~"SFX\SpellBonus.wav");
}
}
task FakeMainLoop {
loop {
if(Frame>0){
Attack;
}
if(Frame==60){
Frame=0;
SetStbMovePosition03(GetCenterX+rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
}
Frame++;
Wait(1);
}
}
task Attack {
Bullets(GetX, GetY, AngA);
AngA=AngA+AngB;
}
task Bullets(x, y, angle){
loop(Amount){
let obj = ObjStbShot_Initialize(x, y, 2, angle+Rotate, RED23, 0, 50, 8, RED);
Rotate=Rotate+360/5
}
}
}
Scripting Level while normaly scripting: Level 4
Scripting Level when only able to use tasks: Nameless Fairy
//easy modo code
let frame = -60;
@MainLoop
{
if (frame==120){doshit; frame = 0;}
frame++;
}
//cool kids code
@Initialize
{
MainTask;
}
task MainTask
{
Wait(60);
loop
{
Wait(120);
doshit;
}
}
@MainLoop
{
yield;
}
script_enemy_main {
#include_function ".\bosslib\Boss.dnh"
let imgBoss = GetCurrentScriptDirectory ~ "img\wriggle.png";
@Initialize {
CreateDebugWindow;
InitializeStbBoss;
LoadGraphic(imgBoss);
SetTexture(imgBoss);
SetGraphicRect(0, 0, 48, 64);
SetX(GetClipMinX);
SetY(GetClipMinY);
SetStbMovePosition03(GetCenterX, GetClipMinY+130, 20, 8);
Attack;
}
@MainLoop {
OutputDebugString(0, "current picture", GetCurrentPicture);
yield;
}
@DrawLoop {
DrawGraphic(GetX, GetY);
}
@Finalize {
}
task Attack {
Wait(72);
loop {
loop {
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
if(GetCurrentPicture > 1){ break; }
Wait(72);
SetStbMovePosition03(GetCenterX+rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
if(GetCurrentPicture > 1){ break; }
Wait(72*3);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
if(GetCurrentPicture > 1){ break; }
Wait(72);
SetStbMovePosition03(GetCenterX-rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
if(GetCurrentPicture > 1){ break; }
Wait(72*3);
}
loop {
let random = rand(0, 360);
Wait(72);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(36);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(36);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(72);
SetStbMovePosition03(GetCenterX+rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
random = rand(0, 360);
Wait(72);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(36);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(36);
CrystalLineSeed(GetX, GetY, 0, 0, BLUE03, 15);
Wait(72);
SetStbMovePosition03(GetCenterX-rand(40, 80), GetClipMinY+rand(120, 200), 20, 5);
}
}
}
task CurvyBullets(angle){
loop(12){
ascent(i in 0..10){
CurvyBullet(GetX, GetY, 3, angle+i*36, YELLOW01, 10);
}
Wait(6);
}
}
task StraightBullets(angle){
loop(12){
ascent(i in 0..10){
ObjStbShot_Initialize(GetX, GetY, 3, angle+i*36, YELLOW02, 10, 100, 12, YELLOW);
}
Wait(17);
}
}
task CurvyBullet(x, y, speed, angle, graphic, delay){
let obj = ObjStbShot_Initialize(x, y, speed, angle, graphic, delay, 50, 8, YELLOW);
Wait(delay);
loop(30){
ObjStbShot_SetAngle(obj, ObjStbShot_GetAngle(obj)+1.5);
Wait(1);
}
Wait(4);
loop(60){
ObjStbShot_SetAngle(obj, ObjStbShot_GetAngle(obj)-1.5);
Wait(1);
}
Wait(4);
loop(60){
ObjStbShot_SetAngle(obj, ObjStbShot_GetAngle(obj)+1.5);
Wait(1);
}
Wait(4);
loop(60){
ObjStbShot_SetAngle(obj, ObjStbShot_GetAngle(obj)-1.5);
Wait(1);
}
}
task CrystalLineSeed(x, y, speed, angle, graphic, delay){
let obj = ObjStbShot_Initialize(x, y, speed, angle, graphic, delay, 150, 32, BLUE);
Wait(delay);
loop(10){
ascent(i in -2..3){
DownCrystal(ObjStbShot_GetX(obj), ObjStbShot_GetY(obj), i, 3, BLUE23, 10);
UpCrystal(ObjStbShot_GetX(obj), ObjStbShot_GetY(obj), i, 3, BLUE23, 10);
ObjStbShot_Initialize(x, y, 2, 0, RED23, delay, 150, 32, RED);
ObjStbShot_Initialize(x, y, 2, 180, RED23, delay, 150, 32, RED);
}
Wait(57);
}
ObjStbShot_FadeDelete(obj);
}
task DownCrystal(x, y, xspeed, yspeed, graphic, delay){
let obj = ObjStbShot_Initialize(x, y, yspeed, 90, graphic, delay, 50, 6, BLUE);
Wait(delay);
while(!Obj_BeDeleted(obj)){
ObjStbShot_SetX(obj, ObjStbShot_GetX(obj)+xspeed);
Wait(1);
}
}
task UpCrystal(x, y, xspeed, yspeed, graphic, delay){
let obj = ObjStbShot_Initialize(x, y, yspeed, 270, graphic, delay, 50, 6, BLUE);
Wait(delay);
while(!Obj_BeDeleted(obj)){
ObjStbShot_SetX(obj, ObjStbShot_GetX(obj)+xspeed);
Wait(1);
}
}
} task CrystalLineSeed(x, y, speed, angle, graphic, delay){
let obj = ObjStbShot_Initialize(x, y, speed, angle, graphic, delay, 150, 32, BLUE);
Wait(delay);
loop(10){
ascent(i in -2..3){
DownCrystal(ObjStbShot_GetX(obj), ObjStbShot_GetY(obj), i, 3, BLUE23, 10);
UpCrystal(ObjStbShot_GetX(obj), ObjStbShot_GetY(obj), i, 3, BLUE23, 10);
ObjStbShot_Initialize(x, y, 2, 0, RED23, delay, 150, 32, RED);
ObjStbShot_Initialize(x, y, 2, 180, RED23, delay, 150, 32, RED);
}
Wait(57);
}
ObjStbShot_FadeDelete(obj);
}
In the Wriggle sample script, I tried to change the angle variation with a speed variation, and then, BOOM.
Not to be mean or anything, but you are terrible at Touhou in General. :V
Mind if I use the video as my bulletforge video preview?
Okay I took a closer look at your code by actually putting it into a script that my engine would read. Yeah, MainLoop scripting isn't going to cut it. You have to learn how to handle everything in tasks.
Well. In some cases, I think that having manual delay is awesome. But in other cases, annoying. Soooo...I'm not going to make two different bullet types for delay or non-delay. That's just completely unnecessary.
why don't we have a bullet that has a built in delay
...and a delay function?
Just do what you planned. It's slightly inconvenient, but people will get used to it easily.I suppose you're right.
Already now I am able to tell: You are a god.
Tested it... WRIGGLE KICKThat won't be for a while. The next release is going to include functions like CreateStbShot01, CreateStbShot02, CreateStbShot11, CreateStbShot12, and laser creation. It will also (finally) have sound effects in the menu and for Aya.
So yeah... still waiting for the comments to be implied, as well as (un)locking of levels.
Already now I am able to tell: You are a god.Quick, give me faith before I die!
Pity he can't sprite, make music, or draw :VI can play music... :ohdear:
because if he could...
Pity he can't sprite, make music, or draw :V
because if he could...
he can't make music
:X
! C:UsersBrandonDocumentsDownloadsPhotography (1).rar: CRC failed in Photographysoundgmgm5.mp3. The file is corrupt
! C:UsersBrandonDocumentsDownloadsPhotography (1).rar: Unexpected end of archive
:XHow do people not know this error? It means that your download got screwed up and cut off early. Delete it and go redownload.
How do people not know this error? It means that your download got screwed up and cut off early. Delete it and go redownload.
pffffff I know that! Thats why I posted it! I've redownloaded it 6 times!
Mirroring might be a good idea because I could download it just fine.
Erm, on another note though... I can't -run- it just fine. I tried going through the music room, selected Wind Tour... and my computer froze. Not just for a short time, not just Danmakufu... I literally had to force power-off my comptuer. I was able to replicate this glitch, so... it wasn't just an accidental thing. I don't know what's going on but I'm not going to restart my computer again to test out if it freezes up on other songs.
On the other hand, everything else seems to work fine 8D Can I possibly suggest making the Nice Shot window customizable in some way? I know in some StB scenes, it doesn't reach the full 2x score bonus possible, while in others it does.
If you want to wait, I'll mirror it for you. That might help.
Mirroring might be a good idea because I could download it just fine.
Erm, on another note though... I can't -run- it just fine. I tried going through the music room, selected Wind Tour... and my computer froze. Not just for a short time, not just Danmakufu... I literally had to force power-off my comptuer. I was able to replicate this glitch, so... it wasn't just an accidental thing. I don't know what's going on but I'm not going to restart my computer again to test out if it freezes up on other songs.
On the other hand, everything else seems to work fine 8D Can I possibly suggest making the Nice Shot window customizable in some way? I know in some StB scenes, it doesn't reach the full 2x score bonus possible, while in others it does.
Could you please? and Thank you!
I have no idea how many things you are aware of, but I may as well list all the little aesthetic things which are still missing:
- Comments, although implemented in-program, aren't implemented in the GUI yet.
- Nothing to indicate which scenes are beaten.
- No unlocking system yet.
- Nothing to save high-scores, or for that matter, best shots.
- No 'attempts' counter. Hell, lets just say that you're lacking a lot of things on the stage select screen *shot*
- Nothing to save replays (I'm pretty sure this is impossible anyway. Thanks, DMF.)
- No running (high)score display in the top left during gameplay.
- No stage number or text photo count in the top right of the screen during game play.
- Aya doesn't have a visible hit-box. (She's supposed to when she focuses.)
- No DS features as of yet, like tilted pictures and orientation switching.
:V
So anyway, this is actually really awesome. I've already began messing around with it and making mock spell-cards, hopefully for perhaps a little project in future. This has only made me more excited. Keep up the excellent work!
Erm, on another note though... I can't -run- it just fine. I tried going through the music room, selected Wind Tour... and my computer froze. Not just for a short time, not just Danmakufu... I literally had to force power-off my comptuer. I was able to replicate this glitch, so... it wasn't just an accidental thing. I don't know what's going on but I'm not going to restart my computer again to test out if it freezes up on other songs.
Apologies if this is old or anything, but have you seen this (http://www.nicovideo.jp/watch/sm10153457) StB DMF clone yet Blargel?
....Aaaaand a video (http://www.youtube.com/watch?v=dCLjf63n160&fmt=22) of said script.
Please don't drop this, it's fucking cool.
Awesome script so far. Well, awesome concept at least (a lot of the details need a LOT of tweaking in the actual danmaku. I'd give more details, but I think the engine was the main point rather than the boss, so I'll let it slide). Great work, and thank you for finally making me not feel like the only person that likes Meltdown - though I didn't know there was an instrumental version!If you thought the danmaku needed tweaking, you should've seen what I had when I was just starting the stage design. I thought everything was relatively balanced for a Lunautic difficulty script when I released it since I was able to beat everything without dying, though not all in one run. Also, that's not just an instrumental version of Meltdown, it's a ZUNified version. :V
Oh god that's freaking awesome... (flashbacks on my rpg crap also :V)You don't suck, lol. But if you feel like it, take whatever little ideas you want. If you want code, look for it yourself, my thing is neatly organized like a labyrinth with no comments to be found anywhere. There's duplicate code too because of the way I organized normal enemies and bosses and because I rushed like hell when it was nearing completion. :V
Well... it seems to me like the bullets reappear at the opposite side when they leave the screen, right?
also... I like you're idea for spawning enemies a lot more than mine... instead of just spawning them at certain points on the map, you spawned them in waves depending on the player's position... a lot easier in terms of coding positions... and it actually looks cooler...
I suck :ohdear:
EDIT: This made me consider highly reconstructing my code... if it's alright with you, can I copy your way of spawning enemies? (ugh... I'll have to recreate the stage setup also.. at least I've only done a few things so far :V)
....You never cease to amaze me, mon.:3
You don't suck, lol. But if you feel like it, take whatever little ideas you want. If you want code, look for it yourself, my thing is neatly organized like a labyrinth with no comments to be found anywhere. There's duplicate code too because of the way I organized normal enemies and bosses and because I rushed like hell when it was nearing completion. :V
//I probably could've shortened this a lot and removed some parts, but it's easier to understand like this
function Collision_Line_Line(x1, y1, x2, y2, x3, y3, x4, y4) //Gets whether 2 widthless segments intersect, actually there's an easier way, but this is easier to understand
{
let lineangle=atan2(y4-y3, x4-x3);
let slope=(y2-y1)/(x2-x1);
if(x2-x1==0){slope=NULL;} //to prevent x/0
let slopeb=(y4-y3)/(x4-x3);
if(x4-x3==0){slopeb=NULL;} //to prevent x/0
if(slopeb==NULL){ //if lineb is vertical
if( (x1<=x3 && x2>=x3)||(x1>=x3 && x2<=x3) ){return true;}else{return false;} //if linea's 2 points lie on opposite sides of lineb, true, else, false
}else if(slopeb==0){ //if lineb is horizontal
if( (y1<=y3 && y2>=y3)||(y1>=y3 && y2<=y3) ){return true;}else{return false;} //if linea's 2 points lie on opposite sides of lineb, true, else, false
}else{
let x5=x1+absolute(x1-x3)*cos(lineangle); //fails at getting the x coordinate of the point where the y's are equal, but you get the idea
let y5=y1+absolute(y1-y3)*sin(lineangle); //fails at getting the y coordinate of the point where the x's are equal, but you get the idea
let x6=x2+absolute(x2-x3)*cos(lineangle); //fails at getting the x coordinate of the point where the y's are equal, but you get the idea
let y6=y2+absolute(y2-y3)*sin(lineangle); //fails at getting the y coordinate of the point where the x's are equal, but you get the idea
if(slopeb>0){ //if lineb y decreases as x increases
if(slope==NULL){
if( (x1<=x5 && x2>=x6)|| (x1>=x5 && x2<=x6) ){return true;}else{return false;} //opposite sides again
}else{
if( x1<x5 && y1<y5 ){ //if point1 is to the left-up of lineb
if( x2>x6 && y2>y6 ){return true;}else{return false;} //if point2 is to the right-down of line b, true, else, false
}else if( x1>x5 && y1>y5 ){ //opposite of previous statement (for angle+180 instances)
if( x2<x6 && y2<y6 ){return true;}else{return false;}
}else if( (x1==x5 && y1==y5) || (x2==x6 && y2==y6) ){return true;}else{return false;} //if point1/2 is collinear with lineb true, else, false
}
}
if(slopeb<0){ //opposite of the entire slopeb>0 if statement
if(slope==NULL){
if( (x1<=x5 && x2>=x6)|| (x1>=x5 && x2<=x6) ){return true;}else{return false;} //opposite sides again
}else{
if( x1>x5 && y1<y5 ){ //if point1 is to the left-up of lineb
if( x2<x6 && y2>y6 ){return true;}else{return false;} //if point2 is to the right-down of line b, true, else, false
}else if( x1<x5 && y1>y5 ){ //opposite of previous statement (for angle+180 instances)
if( x2>x6 && y2<y6 ){return true;}else{return false;}
}else if( (x1==x5 && y1==y5) || (x2==x6 && y2==y6) ){return true;}else{return false;} //if point1/2 is collinear with lineb true, else, false
}
}
}
} //actually... this is already the line to line function you're looking for :V I just want to continue
function Collision_Box_Line(centx, centy, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6) //Gets whether any segment from the center of the box to any corner intersects the line. (if at least one does then the box intersects the line obviously) Admittedly, this could be faster done by just checking the opposite corners, but this method is easier to understand
{ //you need to center cause I'm too lazy to calculate for it :V
let returnval=0; //it's easier than an if statement with 3 ||'s right?
if(Collision_Line_Line(centx, centy, x1, y1, x5, y5, x6, y6)==true){returnval++;}
if(Collision_Line_Line(centx, centy, x2, y2, x5, y5, x6, y6)==true){returnval++;}
if(Collision_Line_Line(centx, centy, x3, y3, x5, y5, x6, y6)==true){returnval++;}
if(Collision_Line_Line(centx, centy, x4, y4, x5, y5, x6, y6)==true){returnval++;}
if(returnval>=1){return true;}else{return false;}
} //notice that this statement can easily be used for a polygon with any number of sides by changing the number of parameters
function PointSideFromLine(x1, y1, x2, y2, x3, y3) //Gets whether a point is on the left or the right of a line
{
let lineangle=atan2(y3-y2, x3-x2);
let x4=x1+absolute(x1-x2)*cos(lineangle); //fails at getting the x coordinate of the point where the y's are equal, but you get the idea
let y4=y1+absolute(y1-y2)*sin(lineangle); //fails at getting the y coordinate of the point where the x's are equal, but you get the idea
if(x1<=x4){return "LEFT";}else{return "RIGHT";}
} //note that I could've just called this multiple times for the first statement, but it's easier to understand like that (at least, for me it is)
function Collision_Box_Laser(centx, centy, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, width) //god... 15 parameters
{
if(PointSideFromLine(centx, centy, x5, y5, x6, y6)=="LEFT"){
if(Collision_Box_Line(centx, centy, x1, y1, x2, y2, x3, y3, x4, y4, x5-width/2, y5-width/2, x6-width/2, y6-width/2)==true){return true;}else{return false;}
//uses the leftmost line of the laser
}else{
if(Collision_Box_Line(centx, centy, x1, y1, x2, y2, x3, y3, x4, y4, x5+width/2, y5+width/2, x6+width/2, y6+width/2)==true){return true;}else{return false;}
//uses the rightmost line of the laser
}
}
Your code is still incorrect I believe.
function PointSideFromLine(x1, y1, x2, y2, x3, y3)
{
let lineangle=atan2(y3-y2, x3-x2);
let slope=(y3-y2)/(x3-x2);
let x4=(y2-y1)/slope+x1; //hope this makes sense... tried morphing y=mx+b into x=(y-b)/m
if(x1<=x4 || x3-x2==0){return "LEFT";}else{return "RIGHT";}
}
function Collision_Segment_Line(x1, y1, x2, y2, x3, y3, x4, y4)
{
if(PointSideFromLine(x1, y1, x3, y3, x4, y4)=="LEFT"){
if(PointSideFromLine(x2, y2, x3, y3, x4, y4)=="RIGHT"){return true;}else{return false;}
}else{
if(PointSideFromLine(x2, y2, x3, y3, x4, y4)=="LEFT"){return true;}else{return false;}
}
}
function Collision_Segment_Segment(x1, y1, x2, y2, x3, y3, x4, y4) //either do this, or find a way to make a GetPOI function (point of intersection) and use Collision_Line_Circle to check if it's on both segments... these 2 things both make sure that it checks segment to segment and not segment to line
{
if(Collision_Segment_Line(x1, y1, x2, y2, x3, y3, x4, y4)==true && Collision_Segment_Line(x3, y3, x4, y4, x1, y1, x2, y2)==true)
{
return true;
}else{
return false;
}
}
function Collision_Box_Line(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6)
{
if(Collision_Segment_Segment(x1, y1, x3, y3, x5, y5, x6, y6)==true || Collision_Segment_Segment(x2, y2, x4, y4, x5, y5, x6, y6)==true)
{
return true;
}else{
return false;
}
}
function Collision_Box_Laser(centx, centy, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, width)
{
if(PointSideFromLine(centx, centy, x5, y5, x6, y6)=="LEFT"){
if(Collision_Box_Line(x1, y1, x2, y2, x3, y3, x4, y4, x5-width/2, y5-width/2, x6-width/2, y6-width/2)==true){return true;}else{return false;}
}else{
if(Collision_Box_Line(x1, y1, x2, y2, x3, y3, x4, y4, x5+width/2, y5+width/2, x6+width/2, y6+width/2)==true){return true;}else{return false;}
}
}